如何使用 CloudFormation 资源导入在现有 S3 存储桶上为 Lambda 创建 Amazon S3 通知配置?

上次更新日期:2022 年 10 月 28 日

我想要使用现有的 S3 存储桶为 AWS Lambda 创建 Amazon Simple Storage Service (Amazon S3) 通知配置。我想通过使用 AWS CloudFormation 导入资源来完成此操作。

简短描述

要在不使用自定义资源的情况下配置 Amazon S3 通知,请执行以下操作:

  1. 使用 Lambda 函数 S3NotificationLambdaFunction 创建模板。此函数添加现有的存储桶 NotificationS3Bucket 通知配置。
  2. 使用资源导入,将模板中指定的现有 NotificationS3Bucket S3 存储桶引入 CloudFormation 管理。
  3. 更新 CloudFormation 堆栈以包含要在 S3 存储桶中激活的属性。

要使用自定义资源,请参阅如何使用 CloudFormation 在现有 S3 存储桶上为 Lambda 创建 Amazon S3 通知配置?

解决方法

重要提示:以下步骤将覆盖 S3 存储桶中的任何现有或手动创建的通知配置。按照以下步骤向导入的 S3 存储桶添加新的通知配置。

使用 Lambda 函数创建 CloudFormation 模板

以下示例模板将创建一个 Lambda 函数,该函数具有运行角色和调用该函数的权限。要使用现有 Lambda 函数,请使用 S3 存储桶中 LambdaConfiguration 属性的 CloudFormation 模板中的函数 Amazon Resource Name (ARN)。

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  Sample template that shows you how to import an existing S3 bucket as an event source for a Lambda function
Parameters:
  NotificationBucket:
    Type: String
    Description: S3 bucket that's used for 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.6
      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:*:*:*'

将现有 S3 存储桶导入您的 CloudFormation 堆栈

1.    打开 AWS CloudFormation 控制台

2.    在导航窗格上,选择 Stack(堆栈),然后选择您之前创建的堆栈。

3.    选择堆栈操作,然后选择将资源导入堆栈

4.    查看导入概览页,然后选择下一步

重要提示:在 CloudFormation 模板中,您导入的每项资源都必须具有 DeletionPolicy属性,且所有其他资源都必须保持不变。例如:

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  Sample template that shows you how to import an existing S3 bucket as an event source for a Lambda function
Parameters:
  NotificationBucket:
    Type: String
    Description: S3 bucket that's used for Lambda event notification
Resources:
  S3NotificationLambdaFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      .
      .
  LambdaInvokePermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      .
      .
  LambdaIAMRole:
    Type: 'AWS::IAM::Role'
    Properties:
      .
      .

  <The preceding resources were already created. Now, add the DeletionPolicy to the preceding stack to import the S3 bucket.>
  NotificationS3Bucket:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Retain
    Properties:
      BucketName: myenv-bucket          #Bucket name to import

5.    在指定模板部分中,选择 Amazon S3 URL 或根据您的要求上传模板文件,然后选择下一步

6.    完成向导中的其余步骤以导入现有资源。有关更多信息,请参阅使用 AWS CloudFormation 控制台将现有资源导入到堆栈

7.    等待堆栈进入 IMPORT_COMPLETE 状态。

更新 CloudFormation 模板

1.    使用您修改的 CloudFormation 模板更新堆栈。

2.    等待堆栈到达 UPDATE_COMPLETE 状态,然后验证 S3 存储桶上的 NotificationConfiguration

3.    在您的 S3 存储桶上开启 Amazon S3 事件通知。在以下示例模板中,存储桶名为 myenv-bucket

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  Sample template that shows you how to import an existing S3 bucket as an event source for a Lambda function
Parameters:
  NotificationBucket:
    Type: String
    Description: S3 bucket that's used for Lambda event notification
Resources:
  S3NotificationLambdaFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      .
      .
  LambdaInvokePermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      .
      .
  LambdaIAMRole:
    Type: 'AWS::IAM::Role'
    Properties:
      .
      .

  <The preceding resources were already created. Now, add the DeletionPolicy to the preceding stack to import the S3 bucket.>
  NotificationS3Bucket:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Retain
    Properties:
      BucketName: myenv-bucket
      NotificationConfiguration:   #Update stack with NotificationConfiguration
          LambdaConfigurations:
              - Event: 's3:ObjectCreated:Put'
                Function: !GetAtt S3NotificationLambdaFunction.Arn
              - Event: 's3:ObjectRemoved:*'
                Function: !GetAtt S3NotificationLambdaFunction.Arn

这篇文章对您有帮助吗?


您是否需要账单或技术支持?