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-1ed3453c5d86
はlambda
タイプで、エンドポイントはarn:aws:lambda:ap-southeast-1:178284945954:function:wowauctions_get_auction_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を返しますが、呼び出しは行われません。どうして?
ラムダの呼び出しを許可するインラインポリシーを追加しました。
{
"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"
]
}
]
}
そしてそれは今働いています。
私にとっての問題は、SourceAccount
パラメータをAWS::Lambda::Permission
私のcloudformationテンプレートで documentation は次のように述べています:
ポリシーを追加するときに--source-accountパラメーターを使用してソースアカウントをLambdaポリシーに追加しないでください。ソースアカウントはAmazon SNSイベントソースではサポートされていないため、アクセスが拒否されます。ソースアカウントはソースARNに含まれているため、セキュリティ上の影響はありません。
SourceAccount
を削除するとすぐに、すべてが正常に動作しました。
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が起動されない):
endpoint
はLambdaのARNと正確に一致する必要があります)これらの基本的なチェックを確認しても呼び出しが表示されない場合は、権限エラーである必要があります。 AWSコンソールでLambdaを開くと、SNSがトリガーとしてリストされているはずです。
比較のために、権限がない場合、SNSは表示されません。
自動デプロイメントを使用していない場合(CloudFormationやTerraformなど)、不足している権限を手動で追加することもできます。
Add triggers
の下のSNS
を選択します(リストを下にスクロールして表示する必要があります)Configure triggers
で、SNSトピックを選択しますAdd
をクリックして、ラムダを保存しますRoboがコメントで述べたように、Principal
ベースの権限を追加することは、これを行う最も簡単な方法です。
"FooFunctionPermission" : {
"Type" : "AWS::Lambda::Permission",
"Properties" : {
"Action" : "lambda:InvokeFunction",
"FunctionName" : { "Ref" : "FooFunction" },
"Principal" : "sns.amazonaws.com"
}
}
この投稿は私がさらに前進するのに役立ちましたが、欠けている部分があります。 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", "")}"
}
同じ問題が発生しました: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 ......
、すべてがピックアップされ、問題なく動作しました。