CloudFormation を使用して、既存の S3 バケットで Lambda 用の Amazon S3 通知設定を作成する方法を教えてください。
既存の Amazon Simple Storage Service (Amazon S3) バケットに AWS Lambda 関数の Amazon S3 通知設定を作成したいと考えています。AWS CloudFormation を使用してこれをやりたいです。
簡単な説明
Amazon S3 通知設定を作成するには、CloudFormation を使用して新しい S3 バケットを作成します。次に、NotificationConfiguration プロパティを使用してそのバケットに通知設定を追加します。または、手動で既存の S3 バケットに通知設定を追加します。
以下のステップは、CloudFormation を使用して既存の S3 バケットに通知設定を追加する方法を示しています。これは、Python 3.9 で作成された Lambda-backed カスタムリソースを使用して行うことができます。カスタムリソースから Lambda 関数を開始することで、この関数が PutBucketNotification API を開始し、S3 バケットに通知設定が追加されます。
注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、AWS CLI の最新バージョンを使用していることを確認してください。
解決方法
重要: 次の手順は、既存の通知設定が作成されていない S3 バケットでの Amazon S3 通知設定にのみ適用されます。S3 バケットに通知設定が既に存在する場合、または手動で作成された通知設定がある場合、次の手順を実行すると、それらの設定は上書きされます。スタックを削除すると、すべての通知が削除されます。ソリューションが機能しているように見えても、ユースケースに関連して最適でない設定が存在する可能性があります。本番環境にデプロイする前に、テスト S3 バケットでソリューションをテストすることをお勧めします。
1. 次のコードを含む CloudFormation テンプレートを LambdaS3.template という名前で作成します。
重要: 次の例では、S3Notification****LambdaFunction リソースに S3 通知設定を追加しています。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) 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 バケットに必要な通知設定が追加され、Lambda 通知に S3 バケットを使用できるようになります。
関連するコンテンツ
- 質問済み 3年前lg...
- 質問済み 5年前lg...
- 質問済み 6年前lg...
- 質問済み 5年前lg...
- AWS公式更新しました 10ヶ月前