如何从S3触发的AWS SNS通知事件中提取存储桶名称等信息?
从SNS通知中提取S3存储桶信息的实现方案
核心方案:直接解析SNS事件中的原始S3消息
你当前的Terraform配置完全符合需求,S3触发SNS时会自动把完整的S3事件结构封装在SNS消息的Message字段内,不需要额外调整现有配置,直接在upload-handlerLambda函数中按以下规则解析即可:
- Lambda被SNS触发时接收到的事件根结构包含
Records数组,每个数组元素对应一条SNS通知 - 单条SNS通知的
sns.Message字段是JSON序列化后的原始S3上传事件,对该字段做JSON反序列化后,得到的结构与S3直接触发Lambda时的事件结构完全相同,你之前适配S3直连场景的解析代码可以直接复用。
代码示例(Python)
import json def lambda_handler(event, context): # 遍历所有SNS通知记录 for sns_record in event['Records']: # 反序列化SNS消息中的原始S3事件 s3_event = json.loads(sns_record['Sns']['Message']) # 提取S3存储桶名称 bucket_name = s3_event['Records'][0]['s3']['bucket']['name'] # 提取上传的文件对象Key object_key = s3_event['Records'][0]['s3']['object']['key'] # 可按需提取其他字段:事件类型、文件大小、存储桶ARN、上传源IP等 event_type = s3_event['Records'][0]['eventName'] file_size = s3_event['Records'][0]['s3']['object']['size'] bucket_arn = s3_event['Records'][0]['s3']['bucket']['arn'] source_ip = s3_event['Records'][0]['requestParameters']['sourceIPAddress'] # 后续根据bucket_name触发对应处理逻辑即可
可选优化方案
如果需要简化解析逻辑或者提前过滤无效事件,可以选择以下配置调整:
- 开启原始消息传递:在
aws_sns_topic_subscription资源中添加raw_message_delivery = true参数,直接将S3原始事件作为SNS消息体传递,去掉SNS额外封装字段,进一步降低解析成本:
resource "aws_sns_topic_subscription" "start_from_upload_topic" { topic_arn = var.upload_notification_topic_arn protocol = "lambda" endpoint = module.start_from_upload_handler.arn # 新增:开启原始消息传递 raw_message_delivery = true }
- 配置SNS消息过滤:如果只需要处理特定存储桶的事件,可以在SNS订阅中添加
filter_policy参数,按存储桶名称提前过滤事件,无需Lambda侧判断无效请求。
内容的提问来源于stack exchange,提问作者Andreas L.
相关产品推荐
相关产品推荐

