Cloudformation - 如何在代码中设置 SNS 订阅的过滤策略?
Posted
技术标签:
【中文标题】Cloudformation - 如何在代码中设置 SNS 订阅的过滤策略?【英文标题】:Cloudformation - how to set filter policy of SNS subscription in code? 【发布时间】:2018-12-13 08:22:19 【问题描述】:更新:Cloudformation 现在支持 SNS 主题过滤器,所以这个问题不再相关,不需要自定义插件或代码。
我正在构建一个包含多个 SNS 主题和多个 Lambda 的系统,每个 Lambda 都从其分配的 SQS 队列中读取消息。 SQS 队列订阅了 SNS 主题,但也有一个过滤策略,因此消息最终会出现在相关的 SQS 队列中。
当我在 AWS 控制台中设置订阅时,它运行良好。
现在我尝试在我的代码中做同样的事情,但 AWS Cloudformation 文档没有描述如何向订阅添加过滤策略。基于python examples here,我尝试了以下方法:
StopOperationSubscription:
Type: "AWS::SNS::Subscription"
Properties:
Protocol: sqs
TopicArn:
Ref: StatusTopic
Endpoint:
Fn::GetAtt: [StopActionQueue, Arn]
FilterPolicy: '"value": ["stop"]'
然后我得到这个错误:
An error occurred: StopOperationSubscription - Encountered unsupported property FilterPolicy.
如何使用 CloudFormation 设置我需要的过滤策略?如果不支持,您有什么替代方案建议?
我希望在我部署无服务器应用程序时自动设置它,无需手动步骤。
【问题讨论】:
我猜这个方法在这里也适用...***.com/questions/33675033/… 现在已经过时了,因为 CFN 现在支持 FilterPolicy aws.amazon.com/blogs/compute/… 【参考方案1】:我是这样解决的:
serverless.yml
plugins:
- serverless-plugin-scripts
custom:
scripts:
commands:
update-topic-filters: sls invoke local -f configureSubscriptions --path resources/lambdaTopicFilters.json
hooks:
before:deploy:finalize: sls update-topic-filters
functions:
configureSubscriptions:
handler: src/configurationLambdas/configureSubscriptions.main
# Only invoked when deploying - therefore, no permissions or triggers are needed.
configureSubscriptions.js
import AWS from 'aws-sdk'
const nameFromArn = arn => arn.split(':').pop()
const lambdaNameFromArn = arn =>
nameFromArn(arn)
.split('-')
.pop()
exports.main = async event =>
const sns = new AWS.SNS( apiVersion: '2010-03-31' )
const params =
const Topics = await sns.listTopics(params).promise()
for (const TopicArn of Topics)
const topicName = nameFromArn(TopicArn)
const filtersForTopic = event[topicName]
if (!filtersForTopic)
continue
const Subscriptions = await sns.listSubscriptionsByTopic( TopicArn ).promise()
for (const Protocol, Endpoint, SubscriptionArn of Subscriptions)
if (Protocol === 'lambda')
const lambdaName = lambdaNameFromArn(Endpoint)
const filterForLambda = filtersForTopic[lambdaName]
if (!filterForLambda)
continue
const setPolicyParams =
AttributeName: 'FilterPolicy',
SubscriptionArn,
AttributeValue: JSON.stringify(filterForLambda),
await sns.setSubscriptionAttributes(setPolicyParams).promise()
// eslint-disable-next-line no-console
console.log('Subscription filters has been set')
顶层是不同的主题名称,下一层是 lambda 名称,第三层是相关订阅的过滤策略:
lambdaTopicFilters.json
"user-event":
"activateUser":
"valueType": ["status"],
"value": ["awaiting_activation"]
,
"findActivities":
"messageType": ["event"],
"value": ["awaiting_activity_data"],
"valueType": ["status"]
,
"system-event":
"startStopProcess":
"valueType": ["status"],
"value": ["activated", "aborted", "limit_reached"]
【讨论】:
【参考方案2】:Cloudformation 昨天才开始支持 FilterPolicy。我也挣扎了一段时间:)
语法
JSON
"Type" : "AWS::SNS::Subscription",
"Properties" :
"DeliveryPolicy" : JSON object,
"Endpoint" : String,
"FilterPolicy" : JSON object,
"Protocol" : String,
"RawMessageDelivery" : Boolean,
"Region" : String,
"TopicArn" : String
YAML
Type: "AWS::SNS::Subscription"
Properties:
DeliveryPolicy: JSON object
Endpoint: String
FilterPolicy: JSON object
Protocol: String
RawMessageDelivery: Boolean,
Region: String
TopicArn: String
参考:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html#cfn-sns-subscription-filterpolicy
https://aws.amazon.com/blogs/compute/managing-amazon-sns-subscription-attributes-with-aws-cloudformation/
【讨论】:
是的,但不清楚在JSON object
中添加什么,OP 询问如何...【参考方案3】:
如果您使用的是无服务器,它现在原生支持 sns 过滤器
functions:
pets:
handler: pets.handler
events:
- sns:
topicName: pets
filterPolicy:
pet:
- dog
- cat
https://serverless.com/framework/docs/providers/aws/events/sns#setting-a-filter-policy
【讨论】:
不再需要使用插件,因为 CF 现在支持过滤器了。 filter 和 filterPolicy 不起作用你能告诉我它什么时候适合你吗?以上是关于Cloudformation - 如何在代码中设置 SNS 订阅的过滤策略?的主要内容,如果未能解决你的问题,请参考以下文章
仅当实体尚不存在时,我是不是可以在 CloudFormation 中设置属性?
AWS Cloudformation 模板 - 在 S3 存储桶中设置区域
如何在弹性 beantalk 负载均衡器中设置自定义标头相关规则
如何描述 cloudformation 跨帐户堆栈信息/名称/详细信息