【问题标题】:AWS SAM YAML File not able to refer to an existing bucket for S3 eventAWS SAM YAML 文件无法为 S3 事件引用现有存储桶
【发布时间】:2020-05-20 20:15:56
【问题描述】:

用例:在为 SAM YAML 文件中的 Lambda 函数创建 S3 事件时引用现有存储桶

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Sample SAM Template for sam-app

Globals:
    Function:
        Timeout: 900
        MemorySize: 2048
        Environment: 
          Variables:
            TABLE_NAME: "111"
            ENDPOINT_OVERRIDE: "222"

Resources:
  SomePull:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: target/demo-1.0.0.jar
      Handler: com.xxxx.run.LambdaFunctionHandler::handleRequest
      Runtime: java8
      Role: arn:aws:iam::aaaa:roaaaale/aaaa/lambdaExecution
      events:
          bucket: codedeploytestxxx
          event: s3:ObjectCreated:*
          rules:
            - prefix: uploads
            - suffix: .jpg
          existing: true

参考:https://github.com/serverless/serverless/pull/6290

我尝试了几种方法,但在创建事件时仍然无法引用现有存储桶,上面缺少什么配置。

执行上述脚本后出现错误:

Invalid. property events not defined for resource of type AWS::Serverless::Function

【问题讨论】:

    标签: amazon-web-services amazon-cloudformation aws-sam aws-sam-cli


    【解决方案1】:

    当您使用 AWS Serverless Application Model (SAM) 时,pull request 来自 a third party Serverless Framework


    属性区分大小写:

    AWS::Serverless::Function documentation

    AWS::Serverless::Function.Events documentation

    AWS::Serverless::Function S3 Event documentation


    将该部分转换为AWS Serverless Application Model (SAM) 语法会导致此错误:

    Resources:
      SomePull:
        Type: AWS::Serverless::Function
        Properties:
          CodeUri: target/demo-1.0.0.jar
          Handler: com.xxxx.run.LambdaFunctionHandler::handleRequest
          Runtime: java8
          Role: arn:aws:iam::aaaa:roaaaale/aaaa/lambdaExecution
          Events:
            Event1:
              Type: S3
              Properties:
                Bucket: codedeploytestxxx
                Events: s3:ObjectCreated:*
                Filter:
                  S3Key:
                    Rules:
                    - Name: prefix
                      Value: uploads
                    - Name: suffix
                      Value: .jpg
    
    [cfn-lint] E0001: Error transforming template: Resource with id [SomePull] is invalid. Event with id [Event1] is invalid. S3 events must reference an S3 bucket in the same template.
    

    AWS Serverless Application Model (SAM) has an issue about referencing an existing S3 bucket here

    【讨论】:

    • 信息很好,但我发现答案一开始很难阅读,因为中间部分是大多数人在高层次上不需要的额外细节。我认为为了在顶部更清楚,您可以提到 SAM 还没有赶上无服务器框架,所以现在不可能直接引用现有的存储桶。不过,这应该被标记为正确答案。谢谢
    【解决方案2】:

    对我有用的是从 lambda 中完全删除事件,然后在 S3 存储桶中添加通知配置以及 Lambda 权限。

    所以你的 lambda 变成:

    SomePull:
      Type: AWS::Serverless::Function
      Properties:
        CodeUri: target/demo-1.0.0.jar
        Handler: com.xxxx.run.LambdaFunctionHandler::handleRequest
        Runtime: java8
        Role: arn:aws:iam::aaaa:roaaaale/aaaa/lambdaExecution
    

    我将现有存储桶导入到单独的堆栈中,然后更新该堆栈以包含以下内容:

      BucketTopicPolicy:
        Type: AWS::Lambda::Permission
        Properties:
          Action: 'lambda:InvokeFunction'
          FunctionName: <my lambda function>
          Principal: 's3.amazonaws.com'
        DeletionPolicy: Delete
    
      Bucket:
        Type: AWS::S3::Bucket
        Properties:
          BucketName: <my existing bucket>
          NotificationConfiguration:
             LambdaConfigurations:
                - Event: 's3:ObjectCreated:*'
                  Function: <my lambda function>
        DeletionPolicy: Retain
        UpdateReplacePolicy: Retain
    

    很可能您可以先导入现有存储桶,然后将 lambda 和 lambda 权限添加到堆栈并简单地更新它。 (请注意,如果堆栈还包含新资源,则不能将现有资源导入堆栈)

    【讨论】:

    • 感谢@kopelitsa 有了这个建议,我能够实现所需的部署设置 - 开发团队一方面使用 AWS SAM 并在本地调用函数,另一方面使用 AWS CDK 来准备/部署将所有内容组合在一起的基础架构。
    猜你喜欢
    • 2020-08-11
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 2021-05-06
    • 2012-09-08
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    相关资源
    最近更新 更多