求AWS EC2实例停止时触发SNS邮件通知的Python Lambda代码
实现前提
- 提前创建好SNS主题,完成邮件接收端的订阅确认
- 为Lambda执行角色配置以下权限:
ec2:DescribeInstances:用于查询实例标签获取实例名称sns:Publish:用于调用SNS发送邮件
- 配置EventBridge规则作为Lambda触发器,事件模式匹配EC2实例停止事件,参考事件模式如下(已完成触发配置可忽略):
{ "source": ["aws.ec2"], "detail-type": ["EC2 Instance State-change Notification"], "detail": { "state": ["stopped"] } }
完整Python Lambda代码
import boto3 # 替换为你自己的SNS主题ARN SNS_TOPIC_ARN = "arn:aws-cn:sns:cn-northwest-1:123456789012:your-sns-topic-name" ec2_client = boto3.client('ec2') sns_client = boto3.client('sns') def lambda_handler(event, context): # 从事件payload中获取实例ID instance_id = event['detail']['instance-id'] # 查询实例详情 response = ec2_client.describe_instances(InstanceIds=[instance_id]) instance_info = response['Reservations'][0]['Instances'][0] # 提取实例名称(Name标签) instance_name = "未设置实例名称" if 'Tags' in instance_info: for tag in instance_info['Tags']: if tag['Key'] == 'Name': instance_name = tag['Value'] break # 构造邮件内容 email_subject = f"AWS EC2实例停止通知: {instance_name}({instance_id})" email_content = f""" 检测到EC2实例已停止,实例信息如下: 实例名称:{instance_name} 实例ID:{instance_id} 实例区域:{context.invoked_function_arn.split(':')[3]} """ # 发送SNS通知 sns_client.publish( TopicArn=SNS_TOPIC_ARN, Subject=email_subject, Message=email_content ) return { 'statusCode': 200, 'body': '通知发送成功' }
注意事项
- EC2的停止事件payload默认仅返回实例ID,实例名称属于自定义标签,必须通过调用
describe_instances接口查询才能获取,这是无法直接从触发事件中拿到实例名的核心原因 - 代码中的
SNS_TOPIC_ARN需要替换为你实际创建的SNS主题的ARN值 - 如果你的AWS资源部署在海外区域,无需修改boto3客户端初始化逻辑,默认会取Lambda所在区域的配置
- 若实例没有配置Name标签,邮件中会显示默认占位符
未设置实例名称,不会影响代码运行
内容的提问来源于stack exchange,提问作者narmada
相关产品推荐
相关产品推荐

