CloudFormation を使用して既存の S3 バケットに Lambda 用の Amazon S3 通知設定を作成する方法を教えてください。

所要時間3分
0

既存の 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 通知に使用できるようになりました。

AWS公式
AWS公式更新しました 9ヶ月前
コメントはありません

関連するコンテンツ