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 ベースのカスタムリソースを作成します。カスタムリソースは、PutBucketNotification API を起動して S3 バケットに通知設定を追加する Lambda 関数を開始します。
**注:**AWS コマンドラインインターフェイス (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 通知に使用できるようになりました。
関連するコンテンツ
- 質問済み 2ヶ月前lg...
- 質問済み 10ヶ月前lg...
- AWS公式更新しました 10ヶ月前
- AWS公式更新しました 2年前
- AWS公式更新しました 3ヶ月前
- AWS公式更新しました 1ヶ月前