aws-lambda - AWS CloudFormation 更新 Lambda 代码以在 S3 存储桶中使用最新版本
问题描述
我正在尝试创建一个支持 Lambda 函数和 AWS CodeBuild 项目的 CloudFormation 模板,用于将 .netcore 源代码构建到 S3 存储桶中已部署的 zip 文件中。以下是详细信息:
- 使用具有多个 Lambda 函数的 GitHub 单一存储库作为 .netcore 解决方案中的不同项目
- 每个 Lambda 函数(又名 .netcore 项目)都有一个 CloudFormation YAML 文件,该文件生成一个包含 Lambda 函数本身和 CodeBuild 项目的堆栈。
- CodeBuild 项目从 GitHub 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
您可以看到构建规范(用于生成和复制)和 CloudFormation 模板(用于 Lambda 函数的源)中使用了相同的工件名称 (RoiCalculatorEventPublisher.zip) 和 S3 存储桶 (deployment-artifacts)。
由于我正在使用 Lambda 使用的相同文件名覆盖 S3 存储桶中的应用程序代码,为什么 Lambda 没有更新为最新代码?
版本号如何工作?是否可以有一个包含工件名称(文件名+版本号)的“系统变量”并在 buildspec和CloudFormation模板中访问相同的“系统变量”?
利用 CloudFormation 模板使用 CodeBuild 生成源代码(通过 buildspec)以及更新使用生成代码的 Lambda 函数的秘诀是什么?
谢谢你。
解决方案
不幸的是,除非您在每次更新时更改“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
推荐阅读
- scala - Scala Coursier 自定义常春藤存储库
- reactjs - 你在哪里存储 gatsby-images?
- java - 在java中检查“荷兰”邮政编码的方法
- arrays - 你如何在 MIPS 汇编语言中创建一个数组
- react-native - I18nManager.swapLeftAndRightInRTL 方法应该如何工作?
- swift - 如何在 Swift 中将颜色与图像相乘?
- python-3.x - Python - 根据列值创建行副本并按迭代次数增加日期
- javascript - 分发带有样式组件的 React UI 库
- grammar - 为什么这个文法不是 LL(1)?
- angular - 如何在angular7中的路由保护内进行http post调用?