You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS中自动停止未带os:linux标签的EC2实例?

实现Lambda自动关停未标记os=linux的EC2实例

我懂你的痛点——找带特定标签的实例停掉很直接,但反过来筛选没有os标签或者**os标签值不是linux**的实例,过滤逻辑确实要绕一下。下面给你一套完整的可落地方案,用Python写Lambda代码,附IAM权限配置和触发方式,一步步来:

一、先给Lambda配置最小权限的IAM角色

Lambda需要权限去查询EC2实例状态和执行停止操作,别直接给全权限,搞个自定义政策更安全:

  • 进入IAM控制台,创建新角色,选择Lambda作为信任实体
  • 给角色附加下面这个自定义政策(或者直接搜索托管政策AmazonEC2ReadOnlyAccess+AmazonEC2StopInstances权限):
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:StopInstances"
            ],
            "Resource": "*"
        }
    ]
}

二、编写Lambda函数代码(Python 3.10+)

核心逻辑是:先拉取指定区域内所有运行中的EC2实例,逐一检查标签——要么没有os标签,要么标签值不是linux,符合条件的就批量停止。

import boto3

def lambda_handler(event, context):
    # 替换成你需要操作的AWS区域,比如'us-east-1'
    TARGET_REGION = 'your-target-region'
    ec2_client = boto3.client('ec2', region_name=TARGET_REGION)
    
    # 先筛选出所有处于运行状态的实例
    running_instances = ec2_client.describe_instances(
        Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]
    )
    
    instances_to_stop = []
    
    # 遍历每个实例,检查标签条件
    for reservation in running_instances['Reservations']:
        for instance in reservation['Instances']:
            instance_id = instance['InstanceId']
            has_valid_tag = False
            
            # 检查实例是否有标签,且包含os=linux(忽略大小写兼容)
            if 'Tags' in instance:
                for tag in instance['Tags']:
                    if tag['Key'] == 'os' and tag['Value'].strip().lower() == 'linux':
                        has_valid_tag = True
                        break
            
            # 没有符合要求的标签,加入停止列表
            if not has_valid_tag:
                instances_to_stop.append(instance_id)
    
    # 批量停止符合条件的实例
    if instances_to_stop:
        print(f"即将停止实例: {instances_to_stop}")
        ec2_client.stop_instances(InstanceIds=instances_to_stop)
        return f"已触发停止操作,共{len(instances_to_stop)}个实例"
    else:
        print("没有需要停止的目标实例")
        return "无操作执行"

代码细节说明:

  • 先过滤running状态的实例,避免做无用功
  • 标签判断加入了大小写兼容(比如Linux或LINUX也会被判定为有效)
  • 批量调用停止接口,减少API请求次数,提升效率

三、测试Lambda函数

  • 在Lambda控制台的「测试」选项卡,创建一个空测试事件(随便填个名称就行)
  • 执行测试后,去CloudWatch日志里查看输出,确认筛选逻辑是否正确——测试阶段可以先把stop_instances换成print,避免误停生产实例

四、设置自动触发(按需配置)

如果需要定期执行(比如每天凌晨清理):

  • 进入Lambda函数的「触发器」选项卡,添加触发器
  • 选择「EventBridge(CloudWatch Events)」,创建定时规则,比如用表达式cron(0 0 * * ? *)(每天UTC时间0点执行)

踩坑提醒

  • 确保Lambda角色的区域和目标EC2区域一致,跨区域的话可以修改代码支持多区域遍历
  • 部分实例可能因状态锁(比如正在初始化)无法停止,可在代码中添加异常捕获,避免整个函数失败

内容的提问来源于stack exchange,提问作者knocknock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:31:02