Amazon web services AWS SNS应该触发我的lambda,但不会
我有一个AWS lambda函数,是我通过apex创建的。我还通过terraform创建了一个SNS主题和订阅 我的主题是:Amazon web services AWS SNS应该触发我的lambda,但不会,amazon-web-services,aws-lambda,amazon-sns,Amazon Web Services,Aws Lambda,Amazon Sns,我有一个AWS lambda函数,是我通过apex创建的。我还通过terraform创建了一个SNS主题和订阅 我的主题是:arn:aws:sns:ap-southest-1:178284945954:fetch\u realm\u auctions 我有一个订阅:arn:aws:sns:ap-southest-1:178284945954:fetch\u realm\u auctions:2da1d182-946d-4afd-91cb-1ed3453c5d86带有lambda类型,端点是:ar
arn:aws:sns:ap-southest-1:178284945954:fetch\u realm\u auctions
我有一个订阅:arn:aws:sns:ap-southest-1:178284945954:fetch\u realm\u auctions:2da1d182-946d-4afd-91cb-1ed3453c5d86
带有lambda
类型,端点是:arn:aws:lambda:ap-southest-1:178284945954:function:wowauctions\u-get\u auctions\u data
我已经确认这是正确的函数ARN。一切似乎都连接正确:
我手动触发SNS:
aws sns publish
--topic-arn arn:aws:sns:ap-southeast-1:178284945954:fetch_realm_auctions
--message '{"endpoint": "https://us.api.battle.net", "realm": "spinebreaker"}'
它返回消息ID,但不进行调用。为什么?我添加了一个内联策略以允许调用lambda:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1474873816000",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:ap-southeast-1:178284945954:function:wowauctions_get_auction_data"
]
}
]
}
正如Robo在评论中提到的,添加基于主体的权限是最简单的方法:
"FooFunctionPermission" : {
"Type" : "AWS::Lambda::Permission",
"Properties" : {
"Action" : "lambda:InvokeFunction",
"FunctionName" : { "Ref" : "FooFunction" },
"Principal" : "sns.amazonaws.com"
}
}
对我来说,问题在于我在cloudformation模板中指定了
SourceAccount
参数,并声明如下:
添加策略时,不要使用--source account参数将源帐户添加到Lambda策略。Amazon SNS事件源不支持源帐户,将导致访问被拒绝。这不会对安全造成影响,因为源帐户包含在源ARN中
我一删除SourceAccount
,一切正常。也有同样的问题:
1) 创建并部署简单lambda
2) 从java sdk手动创建aws sns主题
3) 从java sdk创建sns订阅(sns主题和
(兰姆达)
然后我遇到了一个问题,当从控制台将一些消息推送到主题时,lambda没有截获它。而且,sns触发器甚至没有在lambda中注册
因此,我只需使用以下命令即可解决此问题:
运行
aws lambda add permission…
后,一切都恢复正常。SNS主题需要具有调用lambda的权限
下面是一个用Terraform表示的示例:
# Assumption: both SNS topic and Lambda are deployed in the same region
# resource "aws_sns_topic" "instance" { ... }
# resource "aws_lambda_function" "instance" {... }
# Step 1: Allow the SNS topic to invoke the Lambda
resource "aws_lambda_permission" "allow_invocation_from_sns" {
statement_id = "AllowExecutionFromSNS"
action = "lambda:InvokeFunction"
function_name = "${aws_lambda_function.instance.function_name}"
principal = "sns.amazonaws.com"
source_arn = "${aws_sns_topic.instance.arn}"
}
# Step 2: Subscribe the Lambda to the SNS topic
resource "aws_sns_topic_subscription" "instance" {
topic_arn = "${aws_sns_topic.instance.arn}"
protocol = "lambda"
endpoint = "${aws_lambda_function.instance.arn}"
}
解决此问题的一些一般提示(Lambda未被激发):
addtriggers
下的SNS
(您需要在列表中向下滚动查看)这篇文章帮助我走得更远,但有一部分遗漏了。Terraform将创建错误的订阅。您必须删除
$LATEST
resource "aws_sns_topic" "cloudwatch_notifications" {
name = "aws-${var.service_name}-${var.stage}-alarm"
}
data "aws_lambda_function" "cloudwatch_lambda" {
function_name = "sls-${var.service_name}-${var.stage}-cloudwatch-alarms"
}
resource "aws_lambda_permission" "with_sns" {
statement_id = "AllowExecutionFromSNS"
action = "lambda:InvokeFunction"
function_name = "${replace(data.aws_lambda_function.cloudwatch_lambda.arn, ":$LATEST", "")}"
principal = "sns.amazonaws.com"
source_arn = "${aws_sns_topic.cloudwatch_notifications.arn}"
}
resource "aws_sns_topic_subscription" "cloudwatch_subscription" {
topic_arn = "${aws_sns_topic.cloudwatch_notifications.arn}"
protocol = "lambda"
endpoint = "${replace(data.aws_lambda_function.cloudwatch_lambda.arn, ":$LATEST", "")}"
}
这是对这个问题的一个具体答案——我已经把我的另一个答案从别处删除了 对于Terraform用户,请参见此处: 显示“aws_lambda_权限”资源的使用情况;SNS包含在其中一个示例中,复制于此处:
resource "aws_lambda_permission" "with_sns" {
statement_id = "AllowExecutionFromSNS"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.func.function_name
principal = "sns.amazonaws.com"
source_arn = aws_sns_topic.default.arn
}
Lambda监控选项卡是否显示调用计数?如果是,它是否显示错误计数?您是否尝试在SNS主题(如电子邮件)上添加另一个订阅,以确认消息是在SNS中发送的?Lambda函数是否具有SNS调用的权限?这里有一个例子:@BretzL啊,这就是问题所在。谢谢。很抱歉更改了标题;我想重新标记,删除顶点,遵循标记准则,但随后还需要重新编写标题文本!您也可以添加
“Principal”:“sns.amazonaws.com”
以允许任何sns主题调用任何lambda函数。我花了一点时间才确定此内联策略应应用于sns主题。当然,这节省了我几个小时,希望与AWS权限有某种程度的一致性,让SourceAccount为Cloud Watch事件工作:我从何处复制:)