从 CI/CD 管道部署单个 Lambda 函数
Deploying Single Lambda Function From CI/CD pipeline
我正在处理一个基础设施,并试图弄清楚如何从 CI/CD 管道部署单个 lambda。
假设在一个 repo 中你有 20 个 lambda,你对一个 lambda 进行了更改,而不是部署所有它们,我只想部署更改的 lambda,这样可以缩短部署时间。
我有一个想法,比如检查与 git 的差异,并弄清楚哪些发生了变化,然后只部署那部分功能,但这看起来肯定不是正确的方法.相信有更合适的方法来做到这一点。
我现在正在使用 terraform(转向无服务器框架)我知道 terraform 和无服务器框架在 s3 存储桶上保持状态。然而,在我的情况下,当我 运行 它通过管道时,即使有一个 terraform 状态并且状态没有变化,它仍然会尽可能地部署整个事情(我可能是错的)。我只是想弄清楚我的想法,看看人们是如何用他们的管道做到这一点的。
您似乎添加了 terraform
、serverless-framework (I called it sls)
和 aws-lambda
的标签。所以他们都为你工作。
terraform
- Terraform 本身会处理需要更新 lambda 的差异。但是如果你需要安装相关的包,它不是 lambda 友好的。
serverless framework (sls)
- 用于管理 lambda 函数很好,但作为副作用,它必须与 api 网关一起管理。我不确定 sls 团队是否解决了这个问题。需要一些确认。
SLS 将负责安装相关包。
糟糕的是,sls 无法diff
部署和计划资源。
cloudformation
- 这是 AWS 拥有的 Infrastructure as Code (IaC)
工具来管理 aws 资源,你应该可以用它来管理 lambda 资源。您会遇到与 Terraform 相同的问题,您必须在部署堆栈之前安装相关包。
糟糕的是,cfn (cloudformation) 也没有 diff
功能,此外,它没有适当的工具来管理其 aws cli 命令,您必须使用其他工具,例如shell 脚本、Ansible 甚至 Terraform 来管理 coudformation 模板更新。
aws cdk
- 最新的方法是使用 aws-cdk
,它确实有 diff 特性 cdk diff
最适合你现在的工作,但它是一个非常新的项目,a许多功能仍在等待开发。
你可以拿着这些和 your team's skill sets
一起思考。始终选择您和您的团队最有信心的工具。
由于您在这里似乎同时询问了 Terraform 和 Serverless Framework,我假设您正在寻找一个通用的答案,而不是具体如何使用特定工具解决这个问题。
解决此问题的一种方法是通过在两者之间添加版本选择机制,将构建过程与部署过程分离。这只是意味着在您系统的某个地方,您有一个值可以由您的构建过程写入并由您的部署过程读取,它指示每个 Lambda 函数的 "current" 工件是什么。
当您的构建过程成功完成后,它可以将有关它构建的工件的信息写入适当的位置,然后触发您的部署过程。然后,您的部署过程将读取工件信息并使用它来决定部署什么。
如果您没有对特定功能的当前工件元数据进行任何更改,则部署过程可以看到它并且不会执行任何操作。如果某个特定工件在某种程度上存在缺陷并且您只在部署后才注意到,您可以将工件元数据设置回之前的元数据并重新 运行 部署过程以回滚。如果您选择保留历史版本的数据存储,您还将拥有对当前工件的更改日志,这可能有助于了解导致事件的情况。
不谈具体细节就很难多说了。特别是对于 Terraform,工件元数据存储应该是 Terraform 可以使用 data source 读取的内容。为了展示一个真实的例子,我将任意选择 AWS SSM Parameter Store 作为该工件元数据存储的位置:
data "aws_ssm_parameter" "foo" {
name = "FooFunctionArtifact"
}
locals {
# For this example, we'll assume that the stored parameter is a JSON
# string shaped like this:
# {
# "s3_bucket": "awesomecorp-app-artifacts"
# "s3_key": "/awesomeapp/v1.2.0/function.zip"
# }
foo_artifact = jsondecode(data.aws_ssm_parameter.foo)
}
resource "aws_lambda_function" "foo" {
function_name = "foo"
s3_bucket = local.foo_artifact.s3_bucket
s3_key = local.foo_artifact.s3_key
# etc, etc
}
这方面的技术细节会因您的技术选择而有很大差异。
无论选择何种技术,最主要的是 某处 明确记录了每个功能的最新工件,它由您的构建步骤更新,并且通过您的部署步骤阅读。此模式也适用于其他工件类型,例如 EC2 的 AMI、docker 图像等。
我正在处理一个基础设施,并试图弄清楚如何从 CI/CD 管道部署单个 lambda。
假设在一个 repo 中你有 20 个 lambda,你对一个 lambda 进行了更改,而不是部署所有它们,我只想部署更改的 lambda,这样可以缩短部署时间。
我有一个想法,比如检查与 git 的差异,并弄清楚哪些发生了变化,然后只部署那部分功能,但这看起来肯定不是正确的方法.相信有更合适的方法来做到这一点。
我现在正在使用 terraform(转向无服务器框架)我知道 terraform 和无服务器框架在 s3 存储桶上保持状态。然而,在我的情况下,当我 运行 它通过管道时,即使有一个 terraform 状态并且状态没有变化,它仍然会尽可能地部署整个事情(我可能是错的)。我只是想弄清楚我的想法,看看人们是如何用他们的管道做到这一点的。
您似乎添加了 terraform
、serverless-framework (I called it sls)
和 aws-lambda
的标签。所以他们都为你工作。
terraform
- Terraform 本身会处理需要更新 lambda 的差异。但是如果你需要安装相关的包,它不是 lambda 友好的。serverless framework (sls)
- 用于管理 lambda 函数很好,但作为副作用,它必须与 api 网关一起管理。我不确定 sls 团队是否解决了这个问题。需要一些确认。
SLS 将负责安装相关包。
糟糕的是,sls 无法diff
部署和计划资源。
cloudformation
- 这是 AWS 拥有的Infrastructure as Code (IaC)
工具来管理 aws 资源,你应该可以用它来管理 lambda 资源。您会遇到与 Terraform 相同的问题,您必须在部署堆栈之前安装相关包。
糟糕的是,cfn (cloudformation) 也没有 diff
功能,此外,它没有适当的工具来管理其 aws cli 命令,您必须使用其他工具,例如shell 脚本、Ansible 甚至 Terraform 来管理 coudformation 模板更新。
aws cdk
- 最新的方法是使用aws-cdk
,它确实有 diff 特性cdk diff
最适合你现在的工作,但它是一个非常新的项目,a许多功能仍在等待开发。
你可以拿着这些和 your team's skill sets
一起思考。始终选择您和您的团队最有信心的工具。
由于您在这里似乎同时询问了 Terraform 和 Serverless Framework,我假设您正在寻找一个通用的答案,而不是具体如何使用特定工具解决这个问题。
解决此问题的一种方法是通过在两者之间添加版本选择机制,将构建过程与部署过程分离。这只是意味着在您系统的某个地方,您有一个值可以由您的构建过程写入并由您的部署过程读取,它指示每个 Lambda 函数的 "current" 工件是什么。
当您的构建过程成功完成后,它可以将有关它构建的工件的信息写入适当的位置,然后触发您的部署过程。然后,您的部署过程将读取工件信息并使用它来决定部署什么。
如果您没有对特定功能的当前工件元数据进行任何更改,则部署过程可以看到它并且不会执行任何操作。如果某个特定工件在某种程度上存在缺陷并且您只在部署后才注意到,您可以将工件元数据设置回之前的元数据并重新 运行 部署过程以回滚。如果您选择保留历史版本的数据存储,您还将拥有对当前工件的更改日志,这可能有助于了解导致事件的情况。
不谈具体细节就很难多说了。特别是对于 Terraform,工件元数据存储应该是 Terraform 可以使用 data source 读取的内容。为了展示一个真实的例子,我将任意选择 AWS SSM Parameter Store 作为该工件元数据存储的位置:
data "aws_ssm_parameter" "foo" {
name = "FooFunctionArtifact"
}
locals {
# For this example, we'll assume that the stored parameter is a JSON
# string shaped like this:
# {
# "s3_bucket": "awesomecorp-app-artifacts"
# "s3_key": "/awesomeapp/v1.2.0/function.zip"
# }
foo_artifact = jsondecode(data.aws_ssm_parameter.foo)
}
resource "aws_lambda_function" "foo" {
function_name = "foo"
s3_bucket = local.foo_artifact.s3_bucket
s3_key = local.foo_artifact.s3_key
# etc, etc
}
这方面的技术细节会因您的技术选择而有很大差异。
无论选择何种技术,最主要的是 某处 明确记录了每个功能的最新工件,它由您的构建步骤更新,并且通过您的部署步骤阅读。此模式也适用于其他工件类型,例如 EC2 的 AMI、docker 图像等。