Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services AWS SNS应该触发我的lambda,但不会_Amazon Web Services_Aws Lambda_Amazon Sns - Fatal编程技术网

Amazon web services AWS SNS应该触发我的lambda,但不会

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

我有一个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
类型,端点是:
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未被激发):

  • 我的留言到兰姆达了吗?--订阅SNS主题的电子邮件地址。如果你收到电子邮件,你就会知道消息何时到达主题
  • Lambda订阅了该主题吗?--在AWS控制台(SNS->Topic下)中检查订阅是否正确(端点必须与Lambda的ARN完全匹配)
  • 一旦您确认了这些基本检查,但仍然没有看到任何调用,那么这一定是权限错误。在AWS控制台中打开Lambda时,您应该会看到SNS作为触发器列出:

    为了进行比较,如果缺少权限,您将不会看到SNS:

    如果您未使用自动部署(例如,使用CloudFormation或Terraform),您还可以手动添加缺少的权限:

  • 选择
    addtriggers
    下的
    SNS
    (您需要在列表中向下滚动查看)
  • 在配置触发器中,选择SNS主题
  • 单击添加并保存Lambda

  • 这篇文章帮助我走得更远,但有一部分遗漏了。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事件工作:我从何处复制:)