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

上次更新日期:2020 年 10 月 7 日

我想通过使用 AWS CloudFormation 导入资源,在现有 S3 存储桶上为 AWS Lambda 创建 Amazon Simple Storage Service (Amazon S3) 通知配置。

简短描述

要在不使用自定义资源的情况下配置 Amazon S3 通知,您可以执行以下操作:
  1. 使用 Lambda 函数S3NotificationLambdaFunction创建模板,此函数可添加现有存储桶NotificationS3Bucket通知配置。
  2. 使用资源导入,将现有 S3 存储桶NotificationS3Bucket(在您创建的模板中指定)引入 AWS CloudFormation 管理。
  3. 更新 AWS CloudFormation 堆栈以包含要在 S3 存储桶中启用的属性。

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

解决方案

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

使用 Lambda 函数创建 AWS CloudFormation 模板

以下示例模板将创建一个 Lambda 函数,该函数具有执行角色和调用该函数的权限。要使用现有 Lambda 函数,请使用 S3 存储桶中LambdaConfiguration属性的 AWS CloudFormation 模板中的 Lambda 函数 Amazon 资源名称 (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 which is 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 存储桶导入您的 AWS CloudFormation 堆栈

1.    打开 AWS CloudFormation 控制台

2.    从导航窗格中,选择堆栈,然后选择您之前创建的堆栈。

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

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

重要提示:在 AWS 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 which is 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 状态。

更新 AWS CloudFormation 模板

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

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

3.    在您的 S3 存储桶(以下示例中为myenv-bucket)上启用 Amazon S3 事件通知。例如:

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 which is 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

这篇文章对您有帮助吗?


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