AWS re:Postを使用することにより、以下に同意したことになります 利用規約

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

所要時間3分
0

既存の 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 バケットを使用できるようになります。


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