如何使用 CloudFormation 资源导入在现有 S3 存储桶上为 Lambda 创建 Amazon S3 通知配置?
上次更新日期:2022 年 10 月 28 日
我想要使用现有的 S3 存储桶为 AWS Lambda 创建 Amazon Simple Storage Service (Amazon S3) 通知配置。我想通过使用 AWS CloudFormation 导入资源来完成此操作。
简短描述
要在不使用自定义资源的情况下配置 Amazon S3 通知,请执行以下操作:
- 使用 Lambda 函数 S3NotificationLambdaFunction 创建模板。此函数添加现有的存储桶 NotificationS3Bucket 通知配置。
- 使用资源导入,将模板中指定的现有 NotificationS3Bucket S3 存储桶引入 CloudFormation 管理。
- 更新 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