web-dev-qa-db-ja.com

SNSがラムダをトリガーしないのはなぜですか?

Apexを使用して作成したAWS Lambda関数があります。 SNSトピックとTerraformによるサブスクリプションも作成しました。

私のトピックは:arn:aws:sns:ap-southeast-1:178284945954:fetch_realm_auctions

サブスクリプションがあります:arn:aws:sns:ap-southeast-1:178284945954:fetch_realm_auctions:2da1d182-946d-4afd-91cb-1ed3453c5d86lambdaタイプで、エンドポイントはarn:aws:lambda:ap-southeast-1:178284945954:function:wowauctions_get_auction_data

これが正しい関数ARNであることを確認しました。すべてが正しく配線されているようです:

SNS picture

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を返しますが、呼び出しは行われません。どうして?

14
Kit Sunde

ラムダの呼び出しを許可するインラインポリシーを追加しました。

{
    "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"
            ]
        }
    ]
}

そしてそれは今働いています。

8
Kit Sunde

私にとっての問題は、SourceAccountパラメータをAWS::Lambda::Permission私のcloudformationテンプレートで documentation は次のように述べています:

ポリシーを追加するときに--source-accountパラメーターを使用してソースアカウントをLambdaポリシーに追加しないでください。ソースアカウントはAmazon SNSイベントソースではサポートされていないため、アクセスが拒否されます。ソースアカウントはソースARNに含まれているため、セキュリティ上の影響はありません。

SourceAccountを削除するとすぐに、すべてが正常に動作しました。

2
dmitryb

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が起動されない):

  1. 私のメッセージはラムダに届きますか? -メールアドレスをSNSトピックに登録します。メールを受信すると、トピックにメッセージがいつ到着するかがわかります。
  2. Lambdaはこのトピックを購読していますか? -AWSコンソールで(SNS->トピックの下で)サブスクリプションが正しいかどうかを確認します(endpointはLambdaのARNと正確に一致する必要があります)

これらの基本的なチェックを確認しても呼び出しが表示されない場合は、権限エラーである必要があります。 AWSコンソールでLambdaを開くと、SNSがトリガーとしてリストされているはずです。

enter image description here

比較のために、権限がない場合、SNSは表示されません。

enter image description here

自動デプロイメントを使用していない場合(CloudFormationやTerraformなど)、不足している権限を手動で追加することもできます。

  1. Add triggersの下のSNSを選択します(リストを下にスクロールして表示する必要があります)
  2. Configure triggersで、SNSトピックを選択します
  3. Addをクリックして、ラムダを保存します
1
Philipp Claßen

Roboがコメントで述べたように、Principalベースの権限を追加することは、これを行う最も簡単な方法です。

"FooFunctionPermission" : {
    "Type" : "AWS::Lambda::Permission",
    "Properties" : {
        "Action" : "lambda:InvokeFunction",
        "FunctionName" : { "Ref" : "FooFunction" },
        "Principal" : "sns.amazonaws.com"
    }
}
1
Jonathan

この投稿は私がさらに前進するのに役立ちましたが、欠けている部分があります。 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", "")}"
}
0

同じ問題が発生しました:1)単純なラムダを作成してデプロイしました2)Java sdkから手動でaws snsトピックを作成しました3)Java sdk(subscription SNSトピックとラムダの間)

次に、コンソールからトピックにメッセージをプッシュすると問題が発生しました-ラムダによってインターセプトされませんでした。さらに、snsトリガーはラムダにも登録されていませんでした。

だから私はこのコマンドを使用するだけでこれを修正しました: https://docs.aws.Amazon.com/cli/latest/reference/lambda/add-permission.html

実行後aws lambda add-permission ......、すべてがピックアップされ、問題なく動作しました。

0
Gleb S