如何利用 CloudFormation 在現有 S3 儲存貯體上為 Lambda 建立 Amazon S3 通知組態?
我想利用現有 Amazon Simple Storage Service (Amazon S3) 儲存貯體為 AWS Lambda 函數建立 Amazon S3 通知組態。
簡短描述
若要建立 Amazon S3 通知組態,請使用 CloudFormation 建立新的 S3 儲存貯體。然後,利用 NotificationConfiguration 屬性將通知組態加入儲存貯體。或者,手動將通知組態加入現有 S3 儲存貯體。
下列步驟說明如何利用 CloudFormation 將通知組態加入現有 S3 儲存貯體。若要這麼做,請在 Python 3.9 建立由 Lambda 支援的自訂資源。自訂資源會啟動 Lambda 函數, Lambda 函數 會啟動 PutBucketNotification API 以將通知組態加入您的 S3 儲存貯體。
注意: 如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤,請確認您使用的是最新的 AWS CLI 版本。
解決方案
重要事項: 以下步驟僅適用於不具備現有通知組態的 S3 儲存貯體的 Amazon S3 通知組態。如果您的 S3 儲存貯體已存在現有或手動建立的通知組態,則以下步驟會覆寫這些組態。刪除堆疊後,Amazon S3 會移除所有通知。如果您的解決方案顯示為有效,那麼您的利用案例可能存在較不理想的組態。最佳做法是在將其部署到生產環境之前,先在測試 S3 儲存貯體上測試您的解決方案。
1.建立名為 LambdaS3.template 的 CloudFormation 範本,其中包含下列程式碼:
**重要事項:**在下列範例,您將 S3 通知組態加入 S3NotificationLambdaFunction。您利用 Lambda 函數 CustomResourceLambdaFunction 為 S3NotificationLambdaFunction 新增 S3 通知組態。若要符合您的需求,您可以修改 CustomResourceLambdaFunction 的程式碼。
AWSTemplateFormatVersion: 2010-09-09 Description: >- Sample template to illustrate use of existing S3 bucket as an event source for a Lambda function Parameters: NotificationBucket: Type: String Description: S3 bucket that's used for the Lambda event notification Resources: S3NotificationLambdaFunction: Type: 'AWS::Lambda::Function' Properties: Code: ZipFile: !Join - |+ - - import json - 'def lambda_handler(event,context):' - ' return ''Welcome... This is a test Lambda Function''' Handler: index.lambda_handler Role: !GetAtt LambdaIAMRole.Arn Runtime: python3.9 Timeout: 5 LambdaInvokePermission: Type: 'AWS::Lambda::Permission' Properties: FunctionName: !GetAtt S3NotificationLambdaFunction.Arn Action: 'lambda:InvokeFunction' Principal: s3.amazonaws.com SourceAccount: !Ref 'AWS::AccountId' SourceArn: !Sub 'arn:aws:s3:::${NotificationBucket}' LambdaIAMRole: 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: - 's3:GetBucketNotification' - 's3:PutBucketNotification' Resource: !Sub 'arn:aws:s3:::${NotificationBucket}' - Effect: Allow Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: 'arn:aws:logs:*:*:*' CustomResourceLambdaFunction: Type: 'AWS::Lambda::Function' Properties: Handler: index.lambda_handler Role: !GetAtt LambdaIAMRole.Arn Code: ZipFile: | from __future__ import print_function import json import boto3 import cfnresponse SUCCESS = "SUCCESS" FAILED = "FAILED" print('Loading function') s3 = boto3.resource('s3') def lambda_handler(event, context): print("Received event: " + json.dumps(event, indent=2)) responseData={} try: if event['RequestType'] == 'Delete': print("Request Type:",event['RequestType']) Bucket=event['ResourceProperties']['Bucket'] delete_notification(Bucket) print("Sending response to custom resource after Delete") elif event['RequestType'] == 'Create' or event['RequestType'] == 'Update': print("Request Type:",event['RequestType']) LambdaArn=event['ResourceProperties']['LambdaArn'] Bucket=event['ResourceProperties']['Bucket'] add_notification(LambdaArn, Bucket) responseData={'Bucket':Bucket} print("Sending response to custom resource") responseStatus = 'SUCCESS' except Exception as e: print('Failed to process:', e) responseStatus = 'FAILED' responseData = {'Failure': 'Something bad happened.'} cfnresponse.send(event, context, responseStatus, responseData, "CustomResourcePhysicalID") def add_notification(LambdaArn, Bucket): bucket_notification = s3.BucketNotification(Bucket) response = bucket_notification.put( NotificationConfiguration={ 'LambdaFunctionConfigurations': [ { 'LambdaFunctionArn': LambdaArn, 'Events': [ 's3:ObjectCreated:*' ] } ] } ) print("Put request completed....") def delete_notification(Bucket): bucket_notification = s3.BucketNotification(Bucket) response = bucket_notification.put( NotificationConfiguration={} ) print("Delete request completed....") Runtime: python3.9 Timeout: 50 LambdaTrigger: Type: 'Custom::LambdaTrigger' DependsOn: LambdaInvokePermission Properties: ServiceToken: !GetAtt CustomResourceLambdaFunction.Arn LambdaArn: !GetAtt S3NotificationLambdaFunction.Arn Bucket: !Ref NotificationBucket
2.若要利用 LambdaS3.template 檔案啟動 CloudFormation 堆疊,請使用 CloudFormation 主控台或下列 AWS CLI 命令:
aws cloudformation create-stack --stack-name lambda-s3-notification --template-body file://LambdaS3.template --parameters ParameterKey=NotificationBucket,ParameterValue=existing-bucket-for-lambda-notification --capabilities CAPABILITY_NAMED_IAM --region us-east-1
重要事項: 當您啟動 CloudFormation 堆疊時,您必須傳入 S3 儲存貯體。例如,執行 existing-bucket-for-lambda-notification。
堆疊會為 Amazon S3 建立 Lambda 函數和 Lambda 權限。由於堆疊已將所需的通知組態加入 S3 儲存貯體,因此您現在可利用 S3 儲存貯體來處理 Lambda 通知。
相關內容
- 已提問 1 年前lg...
- 已提問 4 個月前lg...
- AWS 官方已更新 7 個月前
- AWS 官方已更新 1 年前
- AWS 官方已更新 2 年前