CloudFormation을 사용해 기존 S3 버킷에서 Lambda에 대해 Amazon S3 알림 구성을 생성하려면 어떻게 해야 하나요?

3분 분량
0

기존 Amazon Simple Storage Service(S3) 버킷을 사용해 AWS Lambda 함수에 Amazon S3 알림 구성을 생성하려고 합니다.

간략한 설명

Amazon S3 알림 구성을 생성하려면 CloudFormation을 사용해 새 S3 버킷을 생성하세요. 그런 다음 NotificationConfiguration 속성을 사용해 해당 버킷에 알림 구성을 추가합니다. 또는 기존 S3 버킷에 알림 구성을 수동으로 추가할 수 있습니다.

CloudFormation을 사용해 기존 S3 버킷에 알림 구성을 추가하는 방법은 다음 단계를 참고하세요. 이 단계를 실행하려면 Python 3.9에서 Lambda 기반 사용자 지정 리소스를 생성해야 합니다. 사용자 지정 리소스가 Lamda 함수를 실행하며, PutBucketNotification API가 시작되어 S3 버킷에 알림 구성을 추가합니다.

참고: AWS Command Line Interface(AWS CLI) 명령을 실행할 때 오류가 발생하는 경우 최신 AWS CLI 버전을 사용하고 있는지 확인하세요.

해결 방법

중요: 다음 단계는 기존 알림 구성이 없는 S3 버킷의 Amazon S3 알림 구성에만 적용됩니다. S3 버킷에 이미 기존 또는 수동으로 생성한 알림 구성이 있는 상태에서 다음 단계를 따르면 구성이 재정의됩니다. 스택을 삭제하면 Amazon S3가 모든 알림을 제거합니다. 솔루션이 제대로 작동하는 경우 사용 사례에 최적이 아닌 구성이 있을 수 있습니다. 솔루션을 프로덕션 환경에 배포하기 전에 테스트 S3 버킷에서 테스트하는 것이 가장 좋습니다.

1.    다음 코드가 포함된 LambdaS3.template이라는 CloudFormation 템플릿을 생성합니다.

중요: 다음 예에서는 S3NotificationLambdaFunction 리소스에 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, "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 버킷에 추가했기 때문에 Lambda 알림에서 S3 버킷을 사용할 수 있습니다.

AWS 공식
AWS 공식업데이트됨 10달 전