Boto3创建CloudWatch告警实现CPU阈值触发EC2实例自动创建与删除咨询
实现方案
第一部分:告警触发自动创建EC2实例
前置准备
你需要先完成以下资源配置:
- 创建SNS主题,用于接收CloudWatch告警通知
- 创建Lambda函数,编写创建EC2的逻辑,为Lambda配置包含
ec2:RunInstances、ec2:CreateTags的IAM权限 - 将Lambda函数订阅到SNS主题,允许SNS调用Lambda
步骤1:修改告警配置,启用告警动作
你现有代码中ActionsEnabled为False,需要修改为True,同时补充告警触发的SNS主题ARN:
# 替换为你创建的SNS主题ARN SNS_TOPIC_ARN = "arn:aws:sns:region:account-id:your-topic-name" results = client.put_metric_alarm( AlarmName='CPU_Utilization_High', ComparisonOperator='GreaterThanThreshold', EvaluationPeriods=5, MetricName='CPUUtilization', Namespace='AWS/EC2', Period=60, Statistic='Maximum', Threshold=50.0, ActionsEnabled=True, # 改为True启用动作 AlarmActions=[SNS_TOPIC_ARN], # 新增告警触发的SNS主题 AlarmDescription='CPU exceeds 50% for 5 consecutive times', Dimensions=[ { 'Name': 'InstanceId', 'Value': 'i-XXXXXXXXXX' }, ], Unit='Percent' )
步骤2:编写Lambda创建EC2的逻辑
Lambda函数的示例代码如下,创建实例时建议添加专属标签,方便后续识别和管理:
import boto3 ec2 = boto3.resource('ec2') def lambda_handler(event, context): # 启动新EC2实例,参数根据你的需求修改 instances = ec2.create_instances( ImageId='ami-xxxxxxxxxx', # 替换为你的AMI ID InstanceType='t2.micro', # 替换为实例规格 MinCount=1, MaxCount=1, KeyName='your-key-pair', # 替换为你的密钥对名称 SecurityGroupIds=['sg-xxxxxxxxxx'], # 替换为安全组ID SubnetId='subnet-xxxxxxxxxx', # 替换为子网ID # 添加专属标签,方便后续识别自动创建的实例 TagSpecifications=[ { 'ResourceType': 'instance', 'Tags': [ {'Key': 'AutoCreatedByCloudWatch', 'Value': 'True'}, {'Key': 'SourceAlarm', 'Value': 'CPU_Utilization_High'} ] } ] ) print(f"Created new EC2 instance: {instances[0].id}")
第二部分:负载下降自动删除创建的实例
实现逻辑
- 新增一个低CPU利用率的恢复告警,当CPU低于指定阈值连续N次时触发告警
- 告警触发后调用Lambda函数,筛选所有带有
AutoCreatedByCloudWatch=True标签的实例执行删除操作,也可以根据业务需求保留最近1个/指定数量的实例
步骤1:创建低负载告警
SNS_TOPIC_ARN = "arn:aws:sns:region:account-id:your-topic-name" results = client.put_metric_alarm( AlarmName='CPU_Utilization_Low', ComparisonOperator='LessThanThreshold', EvaluationPeriods=5, # 可自定义评估周期 MetricName='CPUUtilization', Namespace='AWS/EC2', Period=60, Statistic='Maximum', Threshold=30.0, # 自定义低负载阈值 ActionsEnabled=True, AlarmActions=[SNS_TOPIC_ARN], AlarmDescription='CPU below 30% for 5 consecutive times', Dimensions=[ { 'Name': 'InstanceId', 'Value': 'i-XXXXXXXXXX' }, ], Unit='Percent' )
步骤2:编写Lambda删除EC2的逻辑
import boto3 ec2 = boto3.client('ec2') def lambda_handler(event, context): # 筛选所有自动创建的EC2实例 response = ec2.describe_instances(Filters=[ {'Name': 'tag:AutoCreatedByCloudWatch', 'Values': ['True']}, {'Name': 'instance-state-name', 'Values': ['running']} ]) instance_ids = [] for reservation in response['Reservations']: for instance in reservation['Instances']: instance_ids.append(instance['InstanceId']) if instance_ids: # 终止实例,可根据需求调整只删除部分实例 ec2.terminate_instances(InstanceIds=instance_ids) print(f"Terminated instances: {instance_ids}")
注意:需要为Lambda额外添加
ec2:DescribeInstances、ec2:TerminateInstances的IAM权限,保证删除操作可以正常执行。
内容的提问来源于stack exchange,提问作者user176556
相关产品推荐
相关产品推荐

