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

3 分钟阅读
0

我想要使用现有的 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

AWS 官方
AWS 官方已更新 1 年前