AWS CloudFormation更新了Lambda代码以在S3存储桶中使用最新版本

时间:2019-09-26 06:04:37

标签: aws-lambda amazon-cloudformation aws-codebuild

我正在尝试创建一个支持Lambda Function和AWS CodeBuild项目的CloudFormation模板,以将.netcore源代码构建到S3存储桶中已部署的zip文件中。  这是详细信息:

  • 在.netcore解决方案中将具有多个Lambda函数的GitHub mono-repo用作不同的项目
  • 每个Lambda函数(也称为.netcore项目)都有一个CloudFormation YAML文件,该文件生成一个包含Lambda函数本身和CodeBuild项目的堆栈。
  • CodeBuild项目是从GitHub Web钩子启动的,该Web钩子从GitHub子项目中检索代码,并使用其buildspec.yaml来控制应如何进行构建。
  • buildspec使用.netcore来构建项目,然后压缩并将输出复制到目标S3存储桶
  • Lambda函数指向S3存储桶获取源代码

一切正常。我正在努力的是如何更新Lambda函数以在S3存储桶中使用更新的已编译源代码。

这是 CloudFormation模板 的子集:

Resources:
Lambda:
    Type: AWS::Lambda::Function
    Properties:
        FunctionName: roicalculator-eventpublisher
        Handler: RoiCalculator.Serverless.EventPublisher::RoiCalculator.Serverless.EventPublisher.Function::FunctionHandler
        Code:
            S3Bucket: deployment-artifacts
            S3Key: RoiCalculatorEventPublisher.zip
        Runtime: dotnetcore2.1

CodeBuildProject:
  Type: AWS::CodeBuild::Project
  Properties:
    Name: RoiCalculator-EventPublisher-Master
    Artifacts:
      Location: deployment-artifacts
      Name: RoiCalculatorEventPublisher.zip
      Type: S3
    Source:
      Type: GITHUB
      Location: https://github.com/XXXXXXX
      BuildSpec: RoiCalculator.Serverless.EventPublisher/buildspec.yml

这是 buildspec.yaml 的子集:

phases:
install:
    runtime-versions:
        dotnet: 2.2
    commands:
      dotnet tool install -g Amazon.Lambda.Tools
  build:
    commands:
      - dotnet restore
      - cd RoiCalculator.Serverless.EventPublisher
      - dotnet lambda package --configuration release --framework netcoreapp2.1 -o .\bin\release\netcoreapp2.1\RoiCalculatorEventPublisher.zip
      - aws s3 cp .\bin\release\netcoreapp2.1\RoiCalculatorEventPublisher.zip s3://deployment-artifacts/RoiCalculatorEventPublisher.zip

您会看到在buildspec(用于生成和复制)和CloudFormation模板(用于Lambda函数的源代码)中使用了相同的工件名称(RoiCalculatorEventPublisher.zip)和S3存储桶(部署工件)。

由于我正在使用相同的Lambda文件名覆盖S3存储桶中的应用程序代码,为什么Lambda不会被最新代码更新?

版本号如何工作?是否可以有一个包含工件名称(文件名+版本号)的“系统变量”,并在buildspec AND CloudFormation模板中访问相同的“系统变量”?

利用CloudFormation模板使用CodeBuild以及使用所生成代码的更新Lambda函数来生成源代码(通过buildspec)的秘诀是什么?

谢谢。

2 个答案:

答案 0 :(得分:2)

不幸的是,除非您在每次更新时都在“ AWS :: Lambda :: Function”资源上更改“ S3Key”,否则CloudFormation不会将其视为更改(不会在压缩代码中查找更改)。

选项

选项1)每次上传时更新S3密钥

选项2)建议的建议是使用AWS SAM编写Lambda模板,然后使用“ cloudformation package”命令打包该模板,这将为S3创建唯一密钥并将文件上传到存储桶。此处的详细信息:https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-deploying.html

编辑1:

为回应您的评论,让我添加一些SAM方法的详细信息:

要将CloudFormation用作管道中Lambda函数的部署工具。部署Lambda函数的基本思路如下:

1)创建Lambda函数的SAM模板

2)基本的SAM模板如下所示:

    AWSTemplateFormatVersion: '2010-09-09'
    Transform: 'AWS::Serverless-2016-10-31'
    Resources:
    FunctionName:
        Type: 'AWS::Serverless::Function'
        Properties:
            Handler: index.handler
            Runtime: nodejs6.10
            CodeUri: ./code

3)添加目录“代码”并将lambda代码文件保留在该目录中

4)安装SAM Cli [1]

5)运行命令以打包并上传:

$ sam package --template-file template.yaml --output-template packaged.yaml --s3-bucket {your_S3_bucket}

6)部署程序包:

$ aws cloudformation deploy --template-file packaged.yaml --stack-name stk1 --capabilities CAPABILITY_IAM

您可以将模板代码(步骤1-2)保留在CodeCommit / Github中,并在代码构建步骤中执行步骤4-5。对于Step6,我建议通过CodePipeline中的CloudFormation操作将输入的“ packaged.yaml”文件作为输入工件进行操作。

另请参阅[2]。

参考文献:

[1]在Linux上安装AWS SAM CLI-https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-linux.html

[2]使用AWS CodePipeline-https://docs.aws.amazon.com/en_us/lambda/latest/dg/build-pipeline.html

为Lambda应用程序构建持续交付管道

答案 1 :(得分:0)

  • 我使用的是aws scp而不是aws cp,但从未遇到过这个问题。
  • 我正在一个具有多个lambda的无服务器体系结构的项目中,其中有多个文件夹,其中只有一个python文件和require.txt文件。
  • 为了方便起见,通常将目录和lambda命名为相同的名称。文件夹email_sender的python文件为email_sender.py,如果需要则为requirement.txt
  • 在安装依赖项后的代码构建中,我仅在下面显示我们如何压缩
      echo "--- Compiling lambda zip: ${d}.zip"
      d=$(tr "_" "-" <<< "${d}")
      zip -q -r ${d}.zip . --exclude ".gitignore" --exclude "requirements.txt" --exclude "*__pycache__/*" > /dev/null 2>&1
      mv ${d}.zip ../../${CODEBUILD_SOURCE_VERSION}/${d}.zip

  • 在复制到s3存储桶时,我们使用scp,如下所示
aws s3 sync ${CODEBUILD_SOURCE_VERSION}/ ${S3_URI} --exclude "*" --include "*.zip" --sse aws:kms --sse-kms-key-id ${KMS_KEY_ALIAS} --content-type "binary/octet-stream" --exact-timestamps