Lambda集成SNS发送消息返回None 无法输出EC2标签检查预期结果
问题根因
SNS消息收到None的核心原因:Python的print()函数执行后仅会把内容输出到控制台,本身没有返回值,默认返回None。你代码中将print()的执行结果赋值给missingtag变量,再将该变量转为字符串作为消息体发送,最终投递的消息内容自然就是None。
现有代码还存在其他逻辑缺陷,无法实现「汇总所有EC2实例检查结果,输出多行内容」的预期:
- SNS发送逻辑内嵌在缺失标签的判断分支中,每遇到1个缺失标签的实例就会单独发1封邮件,其余标签状态(值为unknown、空值、非批准值、正常)的检查结果完全不会被加入消息体
- 重复初始化SNS客户端:函数顶部已经初始化了us-east-1区域的SNS客户端,分支内又重复创建,属于冗余代码
- 标签取值逻辑存在报错风险:直接访问
instance['Tags'],如果遇到刚启动、还未生成标签字段的实例,会直接抛出KeyError导致函数执行失败 - SNS主题存在单词拼写错误:
Dectected正确拼写为Detected
修正后可直接运行的代码
import boto3 from botocore.exceptions import ClientError # 统一初始化客户端与常量,不要在分支内重复创建 AWS_REGION = 'us-east-1' SNS_TOPIC_ARN = '替换为你的实际SNS主题ARN' sns = boto3.client('sns', region_name=AWS_REGION) ec = boto3.client('ec2', region_name=AWS_REGION) DEFAULT_BUILDER_TAG = [{ "Key": "builder", "Value": "unknown" }] APPROVED_BUILDER_VALUES = {'x', 'y', 'z', 'a', 'b'} def lambda_handler(event, context): # 用列表收集所有检查结果,最后统一拼接为多行文本 check_results = [] reservations = ec.describe_instances().get('Reservations', []) for reservation in reservations: for instance in reservation['Instances']: instance_id = instance['InstanceId'] # 兜底处理无Tags字段的实例,避免KeyError tags = {tag['Key']: tag['Value'] for tag in instance.get('Tags', [])} # 场景1:完全不存在builder标签 if 'builder' not in tags: log_text = f"{instance_id} 不存在builder标签,已自动添加值为'unknown'的builder标签" print(log_text) check_results.append(log_text) ec.create_tags(Resources=[instance_id], Tags=DEFAULT_BUILDER_TAG) # 场景2:builder标签值为unknown elif tags['builder'].lower() == 'unknown': log_text = f"{instance_id} 的builder标签值为unknown" print(log_text) check_results.append(log_text) # 场景3:builder标签值为空 elif tags['builder'].strip() == '': log_text = f"{instance_id} 的builder标签值为空,已自动重置为'unknown'" print(log_text) check_results.append(log_text) ec.create_tags(Resources=[instance_id], Tags=DEFAULT_BUILDER_TAG) # 场景4:builder标签值在批准列表内 elif tags['builder'] in APPROVED_BUILDER_VALUES: log_text = f"{instance_id} 的builder标签值符合规范" print(log_text) check_results.append(log_text) # 场景5:builder标签值为非批准值 else: log_text = f"{instance_id} 的builder标签值为非批准值:{tags['builder']}" print(log_text) check_results.append(log_text) # 所有实例检查完成后,统一发送1封汇总SNS消息 if check_results: message_content = "EC2实例builder标签检查结果如下:\n" + "\n".join(check_results) sns.publish( TopicArn=SNS_TOPIC_ARN, Subject='Incorrect Tags Detected', Message=message_content ) return { "statusCode": 200, "checked_instance_count": len(check_results) }
关键改动说明
- 移除了将
print()返回值赋值给变量的错误写法,所有检查日志先存入列表,最终用换行符拼接为完整的多行消息体 - 调整SNS发送时机:所有实例遍历检查完成后仅发送1封汇总邮件,包含全部实例的检查结果,不会再出现零散发信、内容缺失的问题
- 优化标签取值逻辑,通过
instance.get('Tags', [])兜底处理无标签的实例,避免函数意外报错 - 把批准的builder值、默认标签配置抽为常量,后续调整规则不需要改分支判断逻辑
- 空值判断增加了
.strip()处理,避免标签值为全空格的场景漏判 - 移除了未使用的依赖导入(collections、datetime、time、sys、json、logging、ec2资源客户端),减小函数冷启动体积
- 修正了SNS主题的单词拼写错误
内容的提问来源于stack exchange,提问作者skyfire123
相关产品推荐
相关产品推荐

