【问题标题】:How to create S3 and triggered lambda in 2 different cloudformation templates如何在 2 个不同的 cloudformation 模板中创建 S3 和触发 lambda
【发布时间】:2019-10-23 11:30:08
【问题描述】:

可以在单独的 cloudformation 模板中创建 s3 存储桶和触发的 lambda。我想将长期运行的资源堆栈与 lambda 之类的资源堆栈分开,后者会经常更新

当尝试单独创建 lambda 时,它说 lambda 事件中定义的存储桶应该在同一个模板中定义并且不能被引用。

GetFileMetadata:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      FunctionName: !Sub '${targetenv}-lambdaname'
      CodeUri: target-file-0.0.1-SNAPSHOT.jar
      Handler: LambdaFunctionHandler::handleRequest
      Runtime: java8
      Timeout: 30
      MemorySize: 512
      Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
        Variables:
          STAGE: !Sub '${targetenv}'

      Events:
        S3Event:
          Type: S3
          Properties:
            Bucket:
              Ref: MyS3Bucket
            Events:
              - 's3:ObjectCreated:*'

  MyS3Bucket:
      Type: 'AWS::S3::Bucket'
      DependsOn: BucketPermission
      Properties:
          BucketName: !Sub 'bucketname-${targetenv}'
         # LifecycleConfiguration: 
          #  Rules:
           # - ExpirationInDays: 14

【问题讨论】:

    标签: amazon-web-services amazon-s3 aws-lambda amazon-cloudformation aws-sam


    【解决方案1】:

    在最初编写此答案时无法做到这一点,但在这方面已经取得了进展。从那时起,S3 增加了对 SNS 和 SQS 事件的支持为 AWS::S3::Bucket NotificationConfiguration,可以在一个堆栈中声明,然后导入到另一个堆栈。最近,AWS 还添加了 EventBridge 作为另一个选项,请参阅我的other answer

    这在 SAM 版本 2016-10-31 中是不可能的。复制自 SAM 文档中的S3 event source type

    注意:要将 S3 存储桶指定为 Lambda 函数的事件源,必须在同一模板中声明这两个资源。 AWS SAM 不支持将现有存储桶指定为事件源。

    【讨论】:

    • 我不敢相信 2 年后这仍然是正确的,尽管修复此问题的票已经关闭,但我现在面临同样的问题......
    • @KamilJanowski AWS 增加了对 S3 和 EventBridge 集成的支持,请阅读我的updated answer
    【解决方案2】:

    模板正在创建存储桶 (MyS3Bucket)。

    然后,无服务器函数正在引用它:

            Bucket:
              Ref: MyS3Bucket
    

    如果您想从另一个模板中引用该存储桶,您可以导出第一个堆栈中的存储桶名称:

    Outputs:
    
      S3Bucket:
        Description: Bucket that was created
        Value: !Ref MyS3Bucket
        Export:
          Name: Stack1-Bucket
    

    然后,将其导入到第二个堆栈中:

            Bucket:
                Fn::ImportValue:
                  Stack1-Bucket
    

    见:Exporting Stack Output Values - AWS CloudFormation

    【讨论】:

    • 已尝试,仍然给出相同的错误 - 带有 id [S3Event] 的事件无效。 S3 事件必须引用同一模板中的 S3 存储桶。
    • 好的。以上适用于“普通”CloudFormation 模板,但可能不适用于 SAM 模板。
    【解决方案3】:

    2021 年 11 月 21 日,AWS 宣布了 S3 Event Notifications with Amazon EventBridge。因此,您可以部署一个具有启用 EventBridge 集成的 S3 存储桶的堆栈,然后部署具有 Lambda 函数的第二个堆栈,该函数由特定存储桶的 EventBridge 事件触发。

    持久性堆栈:

    AWSTemplateFormatVersion : '2010-09-09'
    Transform: AWS::Serverless-2016-10-31
    Description: 'Stack with S3 bucket with EventBridge event notification enabled'
    
    Parameters:
      BucketName:
        Type: String
        Description: 'Name of the bucket to be created'
    
    Resources:
    
      S3Bucket:
        Type: AWS::S3::Bucket
        Properties:
          BucketName: !Ref BucketName
          NotificationConfiguration:
            EventBridgeConfiguration:
              EventBridgeEnabled: true
    
    #       Alternatively shorthand config
    #       EventBridgeConfiguration: {}
    
    

    应用程序栈:

    AWSTemplateFormatVersion : '2010-09-09'
    Transform: AWS::Serverless-2016-10-31
    Description: Stack with Lambda for procesing S3 events via EventBridge
    
    Parameters:
      BucketName:
        Type: String
        Description: Name of the bucket to listen events from
    
    Resources:
      S3EventProcessor:
        Type: AWS::Serverless::Function
        Properties:
          FunctionName: S3EventListener
          Architectures:
            - arm64
          Runtime: nodejs14.x
          Handler: index.handler
          InlineCode: |
              exports.handler = (event, context) => {
                console.log('event:', JSON.stringify(event));
              }
          Events:
            S3EventBridgeRule:
              Type: EventBridgeRule
              Properties:
                Pattern:
                  source:
                    - aws.s3
                  detail:
                    bucket:
                      name:
                        - !Ref BucketName
    

    通过配置Pattern,您可以过滤事件流以获取更具体的事件,例如Object CreateObject Deleted、文件名、文件扩展名等。请在EventBridge userguide 中查找更多信息

    【讨论】:

      最近更新 更多