Wie kann ich einen CloudFormation-Ressourcenimport verwenden, um eine Amazon-S3-Benachrichtigungskonfiguration für Lambda auf einem vorhandenen S3-Bucket zu erstellen?

Lesedauer: 4 Minute
0

Ich möchte einen vorhandenen Amazon Simple Storage Service (Amazon S3)-Bucket verwenden, um eine Amazon S3-Benachrichtigungskonfiguration für eine AWS-Lambda-Funktion zu erstellen.

Kurzbeschreibung

Um eine Amazon-S3-Benachrichtigungskonfiguration zu erstellen, erstellen Sie einen neuen S3-Bucket mit CloudFormation. Fügen Sie dann mithilfe der Eigenschaft NotificationConfiguration eine Benachrichtigungskonfiguration zu diesem Bucket hinzu. Fügen Sie alternativ manuell eine Benachrichtigungskonfiguration zu einem vorhandenen S3-Bucket hinzu.

Die folgenden Schritte zeigen Ihnen, wie Sie Ihrem vorhandenen S3-Bucket mit CloudFormation eine Benachrichtigungskonfiguration hinzufügen können. Erstellen Sie dazu eine von Lambda-unterstützte benutzerdefinierte Ressource in Python 3.9. Die benutzerdefinierte Ressource initiiert eine Lambda-Funktion, die die PutBucketNotification-API startet, um Ihrem S3-Bucket eine Benachrichtigungskonfiguration hinzuzufügen.

Hinweis: Wenn Sie beim Ausführen von Befehlen der AWS Command Line Interface (AWS CLI) Fehler erhalten, stellen Sie sicher, dass Sie die neueste AWS-CLI-Version verwenden.

Lösung

Wichtig: Die folgenden Schritte gelten nur für Amazon-S3-Benachrichtigungskonfigurationen für S3-Buckets, für die keine vorhandenen Benachrichtigungskonfigurationen vorhanden sind. Wenn Ihr S3-Bucket bereits über eine bestehende oder eine manuell erstellte Benachrichtigungskonfiguration verfügt, überschreiben die folgenden Schritte diese Konfigurationen. Nachdem Sie Ihren Stack gelöscht haben, entfernt Amazon S3 alle Benachrichtigungen. Wenn Ihre Lösung zu funktionieren scheint, liegen in Ihrem Anwendungsfall möglicherweise suboptimale Konfigurationen vor. Es hat sich bewährt, Ihre Lösung in einem Test-S3-Bucket zu testen, bevor Sie sie in einer Produktionsumgebung bereitstellen.

1.Erstellen Sie eine CloudFormation-Vorlage mit dem Namen LambdaS3.template, die den folgenden Code enthält:

Wichtig: Fügen Sie im folgenden Beispiel die S3-Benachrichtigungskonfiguration zur Ressource S3NotificationLambdaFunction hinzu. Verwenden Sie die Lambda-Funktion CustomResourceLambdaFunction, um die S3-Benachrichtigungskonfiguration für S3NotificationLambdaFunction hinzuzufügen. Um Ihre Anforderungen zu erfüllen, können Sie den Code in der Ressource CustomResourceLambdaFunction ändern.

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.Um einen CloudFormation-Stack mit der Datei LambdaS3.template zu starten, verwenden Sie die CloudFormation-Konsole oder den folgenden AWS-CLI-Befehl:

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

Wichtig: Wenn Sie Ihren CloudFormation-Stack starten, müssen Sie Ihren S3-Bucket übergeben. Führen Sie beispielsweise existing-bucket-for-lambda-notification aus.

Der Stack erstellt eine Lambda-Funktion und Lambda-Berechtigungen für Amazon S3. Da der Stack Ihrem S3-Bucket die erforderliche Benachrichtigungskonfiguration hinzugefügt hat, können Sie Ihren S3-Bucket jetzt für Lambda-Benachrichtigungen verwenden.

AWS OFFICIAL
AWS OFFICIALAktualisiert vor einem Jahr