如何解決在 AWS CloudFormation 中將 AWS Lambda 函數訂閱至推送型事件來源時收到的錯誤?
在 AWS CloudFormation 堆疊中,我無法將 AWS Lambda 函數訂閱至 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 儲存貯體和通知組態。此範例使用 Fn::Join 內建函數和 DependsOn 屬性,按下列順序建立資源,以避免循環相依性: 1) IAM 角色,2) Lambda 函數,3) Lambda 許可,然後 4) S3 儲存貯體。如需詳細資訊,請參閱如何在 AWS CloudFormation 中避免 Lambda 事件通知中出現「無法驗證以下目的地組態」錯誤?
相關資訊
相關內容
- 已提問 2 個月前lg...
- 已提問 2 個月前lg...
- 已提問 1 年前lg...
- AWS 官方已更新 4 年前
- AWS 官方已更新 2 年前