首页 > 解决方案 > AWS CloudFormation 更新 Lambda 代码以在 S3 存储桶中使用最新版本

问题描述

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

这一切都很好。我正在努力的是如何更新 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

您可以看到构建规范(用于生成和复制)和 CloudFormation 模板(用于 Lambda 函数的源)中使用了相同的工件名称 (RoiCalculatorEventPublisher.zip) 和 S3 存储桶 (deployment-artifacts)。

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

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

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

谢谢你。

标签: aws-lambdaamazon-cloudformationaws-codebuild

解决方案


不幸的是,除非您在每次更新时更改“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)添加目录“code”,并将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

您可以将模板代码 (Step1-2) 保留在 CodeCommit/Github 中,并在 CodeBuild 步骤中执行 Steps4-5。对于第 6 步,我建议通过 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 为 Lambda 应用程序构建持续交付管道 - https://docs.aws.amazon.com/en_us/lambda/latest/dg/build-pipeline.html


推荐阅读