请帮助我的兄弟姐妹!
我有一个CF堆栈,正在推送一些SNS主题和订阅。其中一些订阅称为Lambda函数。推送堆栈后,我将通过手动向其推送通知来测试调用lambda的SNS主题。 Lambda永远不会射击。当我记录有关该主题的交付状态时,我得到如下信息:
{
"notification": {
"messageMD5Sum": "dfdd100c8699626047a347c435c981fa",
"messageId": "423e1faf-088a-55f8-b2dc-4a86703224c9",
"topicArn": "arn:aws:sns:us-east-2:643112374624:Foobar",
"timestamp": "2019-04-11 17:16:40.096"
},
"delivery": {
"deliveryId": "aae702b2-4787-5c7c-87e6-579b3f3f7f67",
"destination": "arn:aws:lambda:us-east-2:642113479024:function:SomeLambdaFunction",
"providerResponse": "{\"ErrorCode\":\"AccessDeniedException\",\"ErrorMessage\":\"User: sns.amazonaws.com is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-2:642113479024:function:SomeLambdaFunction\",\"lambdaRequestId\":\"Unrecoverable\"}",
"dwellTimeMs": 35,
"attempts": 1,
"statusCode": 403
},
"status": "FAILURE"
}
因此,对我来说完全有意义,我需要授予SNS(或至少是SNS主题)执行特定lambda函数的权限。我如何授予我一个谜。有帮助吗?
通过Web控制台创建Lambda时,将获得此选项。什么是CF当量。
我尝试向我的CloudFormation堆栈模板添加权限:
PolicyName:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt { MyLambdaFunctionName, Arn }
Action: 'lambda:InvokeFunction'
Principal: sns.amazonaws.com
SourceArn: !GetAtt { MySNSTopicName, Arn }
当我尝试部署包含策略的堆栈模板时,它失败并显示以下错误:
Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Invalid template property or properties [PolicyName]
答案 0 :(得分:1)
您需要添加具有以下属性(JSON)的AWS::Lambda::Permission
资源:
{
"Type" : "AWS::Lambda::Permission",
"Properties" : {
"Action" : "lambda:InvokeFunction",
"FunctionName" : {
"Fn::GetAtt": [
"<YOURLAMBDA>",
"Arn"
]
},
"Principal" : "sns.amazonaws.com",
"SourceArn": {
"Ref": "<YOURTOPIC>"
}
}
}
或使用YAML:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt YOURLAMBDA.Arn
Principal: sns.amazonaws.com
SourceArn: !Ref YOURTOPIC
当通知来自您的主题时,这将有效地允许SNS调用Lambda函数。
答案 1 :(得分:0)
为了使其他有相同问题的人希望在此线程中使用该解决方案,我在下面合并了决议。
我们正在创建三件事:
我还有一个此处未定义的Lambda函数(FunctionToDoSomething)。
用于创建以下服务的CloudFormation模板:
MyTopicSNS:
Type: AWS::SNS::Topic
Properties:
DisplayName: MyTopicSNS
TopicName: MyTopicSNS
SendMessageToLambda:
Type: AWS::SNS::Subscription
Properties:
Endpoint: !GetAtt [ FunctionToDoSomething, Arn ]
Protocol: lambda
TopicArn: !Ref MyTopicSNS
Alarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: Alarm
Namespace: "AWS/SQS"
MetricName: "ApproximateNumberOfMessagesVisible"
Dimensions:
- Name: "QueueName"
Value: { "Fn::GetAtt" : [ "ErrorQueue", "QueueName"] }
Statistic: Sum
Period: 300
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: "notBreaching"
AlarmActions:
- !Ref MyTopicSNS
然后,我添加了以下IAM策略,以授予SNS主题执行Lambda函数的权限:
GrantPermissions:
Type: AWS::Lambda::Permission
Properties:
Action: 'lambda:InvokeFunction'
FunctionName: !GetAtt [ FunctionToDoSomething, Arn ]
Principal: 'sns.amazonaws.com'
SourceArn: !Ref MyTopicSNS
一旦我这样做,到该主题的消息就会触发Lambda函数。