Amazon web services Terraform替换Bucket对象而不是版本控制
我正在设置一些地形来管理lambda和s3存储桶,并对s3的内容进行版本控制。创建基础架构的第一个版本很好。发布第二个版本时,terraform将替换zip文件,而不是创建新版本 我尝试在terraform配置中将版本控制添加到s3 bucket中,并将api版本移动到变量字符串中Amazon web services Terraform替换Bucket对象而不是版本控制,amazon-web-services,terraform,Amazon Web Services,Terraform,我正在设置一些地形来管理lambda和s3存储桶,并对s3的内容进行版本控制。创建基础架构的第一个版本很好。发布第二个版本时,terraform将替换zip文件,而不是创建新版本 我尝试在terraform配置中将版本控制添加到s3 bucket中,并将api版本移动到变量字符串中 data "archive_file" "lambda_zip" { type = "zip" source_file = "main.js" output_path = "main.zip
data "archive_file" "lambda_zip" {
type = "zip"
source_file = "main.js"
output_path = "main.zip"
}
resource "aws_s3_bucket" "lambda_bucket" {
bucket = "s3-bucket-for-tft-project"
versioning {
enabled = true
}
}
resource "aws_s3_bucket_object" "lambda_zip_file" {
bucket = "${aws_s3_bucket.lambda_bucket.bucket}"
key = "v${var.api-version}-${data.archive_file.lambda_zip.output_path}"
source = "${data.archive_file.lambda_zip.output_path}"
}
resource "aws_lambda_function" "lambda_function" {
s3_bucket = "${aws_s3_bucket.lambda_bucket.bucket}"
s3_key = "${aws_s3_bucket_object.lambda_zip_file.key}"
function_name = "lambda_test_with_s3_version"
role = "${aws_iam_role.lambda_exec.arn}"
handler = "main.handler"
runtime = "nodejs8.10"
}
我希望输出是另一个zip文件,但lambda现在指向新版本,如果
var.api-version
发生更改,则能够更改回旧版本。Terraform不是为创建这种“工件”对象而设计的,在这种对象中,每个新版本都应该与之前的版本分开
在AWS Lambda早期,将data.archive_文件
数据源添加到Terraform中,当时将值从Terraform传递到Lambda函数的唯一方法是检索预期的zip工件,修改它以包括包含这些设置的附加文件,然后将其写入Lambda
现在AWS Lambda支持环境变量,不再推荐这种模式。相反,部署工件应该由Terraform之外的一些单独的构建过程创建,并记录在Terraform可以发现它们的地方。例如,您可以使用SSM参数存储记录当前所需的版本,然后让Terraform读取该版本以决定检索哪个工件:
data "aws_ssm_parameter" "lambda_artifact" {
name = "lambda_artifact"
}
locals {
# Let's assume that this SSM parameter contains a JSON
# string describing which artifact to use, like this
# {
# "bucket": "s3-bucket-for-tft-project",
# "key": "v2.0.0/example.zip"
# }
lambda_artifact = jsondecode(data.aws_ssm_parameter.lambda_artifact)
}
resource "aws_lambda_function" "lambda_function" {
s3_bucket = local.lambda_artifact.bucket
s3_key = local.lambda_artifact.key
function_name = "lambda_test_with_s3_version"
role = aws_iam_role.lambda_exec.arn
handler = "main.handler"
runtime = "nodejs8.10"
}
这种构建/部署分离允许执行三种不同的操作,而在Terraform中执行所有操作只允许执行一种操作:
- 要发布新版本,您可以运行构建过程(可能在CI系统中),让它将生成的工件推送到S3,并将其记录为SSM参数中的最新版本,然后触发Terraform运行以部署它
- 要在不部署新功能版本的情况下更改基础设施的其他方面,只需运行Terraform而不更改SSM参数,Terraform将保持Lambda功能不变
- 如果发现新版本有缺陷,可以将旧工件的位置写入SSM参数,并运行Terraform来部署以前的版本
这一总体思路可以应用于各种代码构建工件以及Lambda zip文件。例如:使用HashiCorp Packer创建的自定义AMI,使用
Docker build
创建的Docker图像。将构建过程、版本选择机制和部署过程分离提供了一定程度的工作流灵活性,可以支持愉快路径和事件期间采取的任何异常路径。hi这非常有用,感谢分享,我有一个关于Glue的问题,因为它需要从S3存储桶读取脚本,我正想用TrRAFrm把脚本部署到桶中,并把它指向胶水,但是在阅读了Lambda的答案之后,我想知道我是否应该考虑在Terraform之外构建/部署胶二进制文件?有什么建议吗?谢谢