更新: Cloudformation现在支持SNS主题过滤器,因此这个问题不再相关,不需要定制插件或代码。
我正在构建一个包含许多SNS主题的系统,以及许多Lambdas,它们都是从它们分配的SQS队列中读取消息。SQS队列订阅SNS主题,但也有过滤器策略,因此消息将在相关的SQS队列中结束。
当我在AWS控制台中设置订阅时,它工作得很好。
现在,我试图在代码中执行同样的操作,但是AWS Cloudformation文档没有描述如何向订阅中添加筛选策略。基于这里的python示例,我尝试了以下几点:
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设置所需的筛选策略?如果这没有得到支持,你有什么建议来替代?
我希望在部署我的无服务器应用程序时自动设置它,不需要手动步骤。
发布于 2018-08-17 09:27:59
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
参考:
发布于 2018-07-15 17:47:22
我把它修好了:
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"]
}
}
}
发布于 2018-10-25 02:00:54
如果您使用的是“无服务器”,则它现在正以本地方式支持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
https://stackoverflow.com/questions/51181359
复制