如何在CDK中为SNS主题添加订阅过滤器以筛选Lambda触发条件
解决方案
你需要的过滤规则可以直接在SnsEventSource的构造参数中配置实现,核心是要正确指定过滤策略的作用域为SNS消息体,因为S3推送的事件字段默认存放在SNS的消息体中,而非消息属性。
修改后的完整实现代码
const myTopic = new sns.Topic(this, "Topic", {}); myTopic.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ["sns:Publish"], resources: [myTopic.topicArn], principals: [new iam.AccountPrincipal('XXXXXXXXX')] })) const snsEventSource = new lambdaEventSources.SnsEventSource(myTopic, { // 配置过滤规则 filterPolicy: { // 匹配PutObject操作 EventName: sns.SubscriptionFilter.stringFilter({ allowList: ['ObjectCreated:Put'] }), // 匹配特定存储桶名称,替换为你的目标桶名 'S3.Bucket.Name': sns.SubscriptionFilter.stringFilter({ allowList: ['your-target-bucket-name'] }), // 匹配特定文件后缀,可按需求修改后缀列表 'S3.Object.Key': sns.SubscriptionFilter.stringFilter({ matchSuffixes: ['.pdf', '.docx', '.jpg'] }) }, // 核心配置:指定过滤策略作用于SNS消息体,而非默认的消息属性 filterPolicyScope: sns.FilterPolicyScope.MESSAGE_BODY }); myLambda.addEventSource(snsEventSource)
常见失效原因说明
- 未配置
filterPolicyScope参数:SNS过滤默认作用于消息属性,S3推送的事件内容全部在消息体内,缺省该参数会导致过滤规则完全不匹配 - 字段路径写错:S3事件的嵌套字段需要用
.分隔层级,比如桶名的路径是S3.Bucket.Name,对象键的路径是S3.Object.Key,路径错误会导致匹配失败 - CDK版本过低:
FilterPolicyScope相关能力需要CDK v2以上版本,或v1的1.150.0以上版本,低于该版本需要先升级CDK依赖
内容的提问来源于stack exchange,提问作者smallbirds
相关产品推荐
相关产品推荐

