我正在尝试让AWS CloudFormation创建一个模板,该模板将允许我将事件附加到现有的S3存储桶,每当将新文件放入存储桶中的特定目录时,该事件就会触发Lambda函数。我使用以下YAML作为CloudFormation模板的基础,但无法使其正常工作。
---
AWSTemplateFormatVersion: '2010-09-09'
Resources:
SETRULE:
Type: AWS::S3::Bucket
Properties:
BucketName: bucket-name
NotificationConfiguration:
LambdaConfigurations:
- Event: s3:ObjectCreated:Put
Filter:
S3Key:
Rules:
- Name: prefix
Value: directory/in/bucket
Function: arn:aws:lambda:us-east-1:XXXXXXXXXX:function:lambda-function-trigger
Input: '{ CONFIGS_INPUT }'
我尝试过多种方法重写此模板,但均未成功。
答案 0 :(得分:0)
由于您已经提到那些存储桶已经存在,所以这将无法工作。您可以通过这种方式使用CloudFormation,但只能创建一个新存储桶,而如果不是首先不是通过该模板创建该存储桶,则不能修改现有存储桶。
如果您不想重新创建基础结构,仅使用一些将lambda函数订阅到每个存储桶的脚本可能会更容易。只要您具有存储桶和lambda函数的列表,就可以开始使用。
这是Python3中的脚本。假设我们有:
有2个步骤可以使此工作。首先,您需要添加功能策略,该策略将允许s3服务执行该功能。其次,您将一个个地遍历存储桶,将lambda函数订阅给每个存储桶。
import boto3
s3_client = boto3.client("s3")
lambda_client = boto3.client('lambda')
buckets = ["test-bucket-jkg2", "test-bucket-x1gf"]
lambda_function_arn = "arn:aws:lambda:us-east-1:605189564693:function:my_func"
# create a function policy that will permit s3 service to
# execute this lambda function
# note that you should specify SourceAccount and SourceArn to limit who (which account/bucket) can
# execute this function - you will need to loop through the buckets to achieve
# this, at least you should specify SourceAccount
try:
response = lambda_client.add_permission(
FunctionName=lambda_function_arn,
StatementId="allow s3 to execute this function",
Action='lambda:InvokeFunction',
Principal='s3.amazonaws.com'
# SourceAccount="your account",
# SourceArn="bucket's arn"
)
print(response)
except Exception as e:
print(e)
# loop through all buckets and subscribe lambda function
# to each one of them
for bucket in buckets:
print("putting config to bucket: ", bucket)
try:
response = s3_client.put_bucket_notification_configuration(
Bucket=bucket,
NotificationConfiguration={
'LambdaFunctionConfigurations': [
{
'LambdaFunctionArn': lambda_function_arn,
'Events': [
's3:ObjectCreated:*'
]
}
]
}
)
print(response)
except Exception as e:
print(e)
答案 1 :(得分:0)
您可以编写一个自定义资源来执行此操作,实际上,这就是我在工作中针对同一问题所做的最终结果。在最简单的级别上,定义一个接受放置存储桶通知配置的lambda,然后仅使用传递给它的数据调用放置存储桶通知api。
如果您希望能够在不同的cloudformation模板之间控制不同的通知,则它要复杂一些。您的自定义资源lambda将需要读取来自S3的现有通知,然后根据从CF传递给它的数据来更新这些通知。