【问题标题】:How to pass commit_id as lambda zip file name (s3 object_name) from codepipeline to cloudformation template如何将 commit_id 作为 lambda zip 文件名(s3 object_name)从 codepipeline 传递到 cloudformation 模板
【发布时间】:2021-07-23 19:11:37
【问题描述】:

为了让 lambda 从 s3 存储桶获取更新的 zip 文件,每当我更新文件时,我都会将 commit-id 添加到 zip 文件名并上传到 s3 存储桶。 (s3 存储桶版本控制也被激活)。这是我所做的:

我有一个 CloudFormation 模板,它创建了一个 lambda 函数,而 lambda 从一个 s3 存储桶中获取压缩代码。 为了拥有 CI/CD,我创建了一个 CodePipeline,它在 buildpart(buidspec) 中从 python 脚本创建一个 zipfile 并将其上传到 s3 存储桶,它使用 $CODEBUILD_RESOLVED_SOURCE_VERSION 将 commit-id 添加到 zip 文件名

代码构建:

CodeBuild:
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
        Type: LINUX_CONTAINER
      Name: !Sub ${AWS::StackName}-buildzipfile
      ServiceRole: !GetAtt CodeBuildRole.Arn
      Source:
        Type: CODEPIPELINE
        BuildSpec: |-
          version: 0.2
          phases:
            install:
              runtime-versions:
                python: 3.8
            build:
              commands:
                - cd src
                - pip install boto3
                - pip install zip_files
                - echo $CODEBUILD_RESOLVED_SOURCE_VERSION
                - python codebuildzip.py $CODEBUILD_RESOLVED_SOURCE_VERSION
                - echo "Uploaded LambdaFunction to S3 bucket."

CloudFormation.yml

LambdaFunction:
    Type: 'AWS::Lambda::Function'
    Properties: 
      Code:
        S3Bucket: !Ref 'LambdaZipfileBucket'
        S3Key: lambda_function.zip  ####Here it should be like: lambda_function_{commitid}.zip
      Description: Monitor Lambda Function
      Handler: 'lambda_function.lambda_handler'
      Role: !GetAtt 
        - LambdaExecutionRole
        - Arn
      Runtime: python3.7  
      Environment:
        Variables:
           myvar1: "value1"

在我正在部署 cloudformation 模板的 CodePipeline 中,我需要将 lambda zip 文件名发送到 cloudformation,以便 Lambda 获取更新的 S3Key。

CodePipeline:
    Type: 'AWS::CodePipeline::Pipeline'
    #checking changes of the template and deploying it.
    Properties:
      RoleArn: !GetAtt CodePipelineRole.Arn
      ArtifactStore:
        Location: !Ref 'ArtifactStoreBucket'
        Type: S3
      Name: !Ref 'PipelineName'
      Stages:
      - Name: Build 
          Actions: 
            - Name: CodeBuild 
              InputArtifacts: 
                - Name: SrcOutput 
              ActionTypeId: 
                Category: Build
                Owner: AWS 
                Version: 1 
                Provider: CodeBuild
              Configuration: 
                ProjectName: !Ref CodeBuild
              OutputArtifacts:
                - Name: BuildOutput 
              RunOrder: '1'    
        - Name: Deploy
          Actions:
            - Name: CreateChangeSet
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CloudFormation
                Version: '1'
              InputArtifacts:
                - Name: SrcOutput
              Configuration:
                ActionMode: CHANGE_SET_REPLACE
                RoleArn: !GetAtt CloudFormationExecutionRole.Arn
                Capabilities: CAPABILITY_NAMED_IAM
                StackName: !Ref StackName
                ChangeSetName: !Ref ChangeSetName
                TemplatePath: "SrcOutput::templates/CloudFormation.yml"
              RunOrder: '2'  
            - Name: ExecuteChangeSet
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CloudFormation
                Version: '1'
              Configuration:
                ActionMode: CHANGE_SET_EXECUTE
                ChangeSetName: !Ref ChangeSetName
                RoleArn: !GetAtt CloudFormationExecutionRole.Arn
                StackName: !Ref StackName
              RunOrder: '3'                     

我的问题是如何通过代码管道将 s3 对象名称发送到模板文件? 或者是否有更好的方法让 lambda 函数获取更新的 s3 对象?

我已经搜索了很多,一些帖子谈到了使用“Fn::GetArtifactAtt”或将 zipfilename 保存到 ssm 并从 ssm 获取它,但是我无法让它们解决。 例如,添加以下参数似乎不正确,因为 ObjectKey 是包含由 CodePipeline 生成的工件的 .zip 文件的名称,而不是 s3 对象的名称:

 ParameterOverrides: |
                  {
                    "S3Key" : { "Fn::GetArtifactAtt" : ["SrcOutput", "ObjectKey"]}
                  }

任何帮助将不胜感激。

【问题讨论】:

    标签: amazon-s3 aws-lambda amazon-cloudformation aws-codepipeline


    【解决方案1】:

    还有其他几种方法可以潜在地解决此问题,但要与您当前的方法保持一致。

    https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-variables.html

    管道的第一阶段必须至少包含一个源操作。您可以使用如下命名空间(SourceVariables)声明它:

            - Name: Checkout
              Actions:
                - ActionTypeId:
                    Category: Source
                    Owner: AWS
                    Provider: CodeStarSourceConnection
                    Version: "1"
                  Configuration: 
                    ConnectionArn: !Ref CodeStarConnectionArn
                    FullRepositoryId: !Ref BitBucketRepo
                    BranchName: !Ref BitBucketRepoReleaseBranch
                    OutputArtifactFormat: "CODE_ZIP"
                  Name: Checkout
                  Namespace: SourceVariables
                  OutputArtifacts:
                    - Name: !Ref SourceArtifactName
                  RunOrder: 1
    

    现在可以在您的管道定义中使用“#{SourceVariables.CommitId}”,例如

     ParameterOverrides: !Sub |
                   {
                   "CommitId" : '#{SourceVariables.CommitId}'
                   }
    

    那么你的 CF 模板可能是这样的:

    Parameters:
     CommitId:
      Type: String
    
    
    Resources:
     LambdaFunction:
        Type: 'AWS::Lambda::Function'
        Properties: 
          Code:
            S3Bucket: !Ref 'LambdaZipfileBucket'
            S3Key: !Sub lambda_function_${CommitId}.zip 
          Description: Monitor Lambda Function
          Handler: 'lambda_function.lambda_handler'
          Role: !GetAtt 
            - LambdaExecutionRole
            - Arn
          Runtime: python3.7  
          Environment:
            Variables:
               myvar1: "value1"
    

    【讨论】:

    • 谢谢。这看起来很棒。当我得到另一个项目时,我一定会尝试这个。我在我的项目上另辟蹊径。
    猜你喜欢
    • 2019-04-03
    • 2021-07-26
    • 2018-02-25
    • 2021-03-27
    • 1970-01-01
    • 2021-09-23
    • 2020-11-06
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多