Amazon web services 使用AWS CloudFormation设置S3存储桶级别事件
我试图让AWS CloudFormation创建一个模板,该模板允许我将事件附加到现有的S3存储桶中,每当新文件放入存储桶中的特定目录时,该事件将触发Lambda函数。我使用以下YAML作为CloudFormation模板的基础,但无法使其工作Amazon web services 使用AWS CloudFormation设置S3存储桶级别事件,amazon-web-services,amazon-s3,aws-lambda,amazon-cloudformation,Amazon Web Services,Amazon S3,Aws Lambda,Amazon Cloudformation,我试图让AWS CloudFormation创建一个模板,该模板允许我将事件附加到现有的S3存储桶中,每当新文件放入存储桶中的特定目录时,该事件将触发Lambda函数。我使用以下YAML作为CloudFormation模板的基础,但无法使其工作 --- AWSTemplateFormatVersion: '2010-09-09' Resources: SETRULE: Type: AWS::S3::Bucket Properties: BucketName
---
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 }'
我尝试了许多不同的方法来重写此模板,但都没有成功。因为您提到这些桶已经存在,所以这是行不通的。您可以以这种方式使用CloudFormation,但只能创建一个新的bucket,如果bucket最初不是通过该模板创建的,则不能修改现有bucket 如果您不想重新创建您的基础设施,只需使用一些脚本将lambda函数订阅到每个bucket可能会更容易。只要您有一个bucket列表和lambda函数,就可以开始了 下面是Python3中的一个脚本。假设我们有:
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)
您可以编写一个自定义资源来实现这一点,事实上,这就是我在工作中为同一个问题所做的。在最简单的级别上,定义一个lambda,它接受一个put bucket通知配置,然后使用传递给它的数据调用put bucket通知api
如果您希望能够跨不同的cloudformation模板控制不同的通知,那么它就有点复杂了。您的自定义资源lambda将需要从S3读取现有通知,然后根据从CF传递给它的数据更新这些通知。您得到了什么错误?您是否在S3存储桶上添加了lambda调用权限?我收到了一些不同的错误,这取决于我所做的轻微更改,最近,我在只读取
Properties:
的行中遇到了一个YAML格式不正确的错误。lambda函数通常在AWS中的lambda函数服务下定义。我能够触发它并将一组集群配置输入传递给触发lambda函数也很重要。lambda函数将触发一个状态机,该状态机使用该输入来启动EMR集群。我最好能够使用CloudFormation进行设置,这样CloudFormation更新可以在下次触发事件时发送要使用的更改。你知道怎么做吗?我不明白。CloudFormation只是IaaC(对您的环境的描述)CloudFormation update可以在下次触发事件时发送要使用的更改吗?
什么样的更改并将其发送到何处?甚至会触发CF更新?该事件将以何种方式以及如何修改模板?您是否计划以编程方式构建模板?