Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services 使用AWS CloudFormation设置S3存储桶级别事件_Amazon Web Services_Amazon S3_Aws Lambda_Amazon Cloudformation - Fatal编程技术网

Amazon web services 使用AWS CloudFormation设置S3存储桶级别事件

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

我试图让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 }'

我尝试了许多不同的方法来重写此模板,但都没有成功。

因为您提到这些桶已经存在,所以这是行不通的。您可以以这种方式使用CloudFormation,但只能创建一个新的bucket,如果bucket最初不是通过该模板创建的,则不能修改现有bucket

如果您不想重新创建您的基础设施,只需使用一些脚本将lambda函数订阅到每个bucket可能会更容易。只要您有一个bucket列表和lambda函数,就可以开始了

下面是Python3中的一个脚本。假设我们有:

  • 两个桶分别称为test-bucket-jkg2test-bucket-x1gf
  • 带有arn的lambda函数:arn:aws:lambda:us-east-1:605189564693:函数:my_func
  • 有两个步骤可以实现这一点。首先,您需要添加允许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)
    

    您可以编写一个自定义资源来实现这一点,事实上,这就是我在工作中为同一个问题所做的。在最简单的级别上,定义一个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更新?该事件将以何种方式以及如何修改模板?您是否计划以编程方式构建模板?