AWS CloudFormation のプッシュベースのイベントソースに AWS Lambda 関数をサブスクライブしたときに表示されるエラーを解決するにはどうすればよいですか?
AWS Lambda 関数を AWS CloudFormation スタック内の Amazon Simple Storage Service (Amazon S3) イベント通知、または Amazon Simple Notification Service (Amazon SNS) トピックにサブスクライブできません。AWS::Lambda::EventSourceMapping リソースを使用すると、「イベントソースを認識できません。kinesis または dynamodb ストリームにする必要があります」というエラーが表示されます。
簡単な説明
AWS::Lambda::EventSourceMapping リソースは、Amazon DynamoDB イベントストリームや Amazon Kinesis などのプルベースのイベントソース用に設計されています。Amazon S3 イベント通知や Amazon SNS メッセージなどのプッシュベースのイベントソースでは、イベントソースが Lambda 関数を呼び出す必要があります。プッシュイベントソースが Lambda 関数を呼び出すには、その関数のリソースポリシーがサポートされているイベントソースを承認している必要があります。
解決方法
AWS CloudFormation テンプレートで、AWS::Lambda::Permission リソースを使ってリソースベースのポリシーを追加します。
たとえば、次のリソースベースのポリシーは、Amazon SNS トピックが Lambda 関数を呼び出せるようにします。
"LambdaResourcePolicy": { "Type": "AWS::Lambda::Permission", "Properties": { "FunctionName" : { "Ref" : "MyFunction" }, "Principal": "sns.amazonaws.com", "Action": "lambda:InvokeFunction", "SourceArn" : { "Ref" : "MySNSTopic" } } }
Amazon SNS トピックのイベントソースには、必要な許可を持つトピックポリシーを定義する必要があります。
Amazon S3 のイベントソースについては、Lambda 関数を Amazon S3 バケットにサブスクライブする通知設定文が必要です。例:
{ "AWSTemplateFormatVersion": "2010-09-09", "Parameters": { "BucketPrefix": { "Type": "String", "Default": "test-bucket-name" } }, "Resources": { "EncryptionServiceBucket": { "DependsOn": "LambdaInvokePermission", "Type": "AWS::S3::Bucket", "Properties": { "BucketName": { "Fn::Sub": "${BucketPrefix}-encryption-service" }, "NotificationConfiguration": { "LambdaConfigurations": [ { "Function": { "Fn::GetAtt": [ "AppendItemToListFunction", "Arn" ] }, "Event": "s3:ObjectCreated:*", "Filter": { "S3Key": { "Rules": [ { "Name": "suffix", "Value": "zip" } ] } } } ] } } }, "LambdaInvokePermission": { "Type": "AWS::Lambda::Permission", "Properties": { "FunctionName": { "Fn::GetAtt": [ "AppendItemToListFunction", "Arn" ] }, "Action": "lambda:InvokeFunction", "Principal": "s3.amazonaws.com", "SourceAccount": { "Ref": "AWS::AccountId" }, "SourceArn": { "Fn::Sub": "arn:aws:s3:::${BucketPrefix}-encryption-service" } } }, "AppendItemToListFunction": { "Type": "AWS::Lambda::Function", "Properties": { "Handler": "index.handler", "Role": { "Fn::GetAtt": [ "LambdaExecutionRole", "Arn" ] }, "Code": { "ZipFile": { "Fn::Join": [ "", [ "exports.handler = function(event, context) {", "console.log('Received event: ', JSON.stringify(event, null, 2));", "};" ] ] } }, "Runtime": "nodejs8.10" } }, "LambdaExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/", "Policies": [ { "PolicyName": "root", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:*" ], "Resource": "arn:aws:logs:*:*:log-group:/path/<log-group-name>:log-stream:<log-stream-name>" } ] } } ] } } } }
前出の例では、S3 バケットと通知設定が同時に作成されました。この例は、1) IAM ロール、2) Lambda 関数、3) Lambda のアクセス許可、そして 4) S3 バケットという順序でリソースを作成するために Fn::Join 組み込み関数と DependsOn 属性を使用することによって、循環依存を回避します。詳細については、AWS CloudFormation で Lambda イベント通知を使用する際の「Unable to validate the following destination configurations」(次の送信先設定を検証できません) というエラーを回避するにはどうすればよいですか?を参照してください。
関連情報

関連するコンテンツ
- 質問済み 4年前lg...
- 質問済み 2ヶ月前lg...
- 質問済み 15日前lg...
- 質問済み 3年前lg...
- AWS公式更新しました 1年前