我可以让 terraform 保留旧版本的对象吗?
Can I have terraform keep the old versions of objects?
terraform 的新手,所以它可能不应该以这种方式工作。我想使用 aws_s3_bucket_object 将包上传到存储桶 - 这是应用程序部署的一部分。我将更改每次部署的包,我想保留旧版本。
resource "aws_s3_bucket_object" "object" {
bucket = "mybucket-app-versions"
key = "version01.zip"
source = "version01.zip"
}
但是在 运行 之后,为了将来的部署,我将要上传版本 02,然后是版本 03 等。Terraform 用新的预期行为替换旧的 zip .
但是有没有办法让 terraform 不破坏旧版本?这是这里受支持的用例还是这不是我应该使用 terraform 的方式?如果 terraform 没有官方支持做我在这里想做的事情,我不想用一个丑陋的 hack 来强迫它。
我当然可以通过脚本调用 S3 api,但最好能将其与此应用程序的其余 terraform 定义一起定义。
目前,您告诉 terraform 管理一个 aws_s3_bucket_object
并且 terraform 负责它的整个生命周期,这意味着 terraform 也会在发现任何更改时替换该文件。
您可能正在寻找的是 null_resource. You can use it to run a local-exec 配置器,它可以使用脚本上传您需要的文件。这样,旧文件就不会被删除,因为它不是由 terraform 直接管理的。您仍然会通过脚本调用 API,但上传到 s3 的整个过程仍将包含在您的 terraform apply
步骤中。
这里是null_resource
的大纲:
resource "null_resource" "upload_to_s3" {
depends_on = ["<any resource that should already be created before upload>"]
...
triggers = ["<A resource change that must have happened so terraform starts the upload>"]
provisioner "local-exec" {
command = "<command to upload local package to s3>"
}
}
在使用 Terraform 进行应用程序部署时,推荐的方法是将构建步骤与部署步骤分开,仅对后者使用 Terraform。
构建步骤——使用单独的工具实现,具体取决于部署方法——的职责是生成一些工件(存档、docker 容器、虚拟机映像等),将其发布到某处,然后将其位置或标识符传递给 Terraform 进行部署。
构建和部署之间的这种分离允许更复杂的情况,例如如果新版本有问题回滚到旧工件(而不重建它)。
在简单的场景中,可以使用 Input Variables 将工件位置传递给 Terraform。例如,在构建过程将 zip 文件写入 S3 的情况下,您可以定义如下变量:
variable "archive_name" {
}
然后可以使用 ${var.archive_name}
插值语法将其传递给任何需要它的资源。要部署特定工件,请使用 -var
:
在命令行上传递其名称
$ terraform apply -var="archive_name=version01.zip"
一些组织喜欢在某种数据存储中记录每个应用程序的 "current" 版本,例如 HashiCorp Consul, and read it using a data source。这种方法可以更容易地在自动构建管道中进行编排,因为它允许使用这个单独的数据存储在构建和部署步骤之间间接传递存档名称,而无需将任何不寻常的参数传递给 Terraform 本身。
terraform 的新手,所以它可能不应该以这种方式工作。我想使用 aws_s3_bucket_object 将包上传到存储桶 - 这是应用程序部署的一部分。我将更改每次部署的包,我想保留旧版本。
resource "aws_s3_bucket_object" "object" {
bucket = "mybucket-app-versions"
key = "version01.zip"
source = "version01.zip"
}
但是在 运行 之后,为了将来的部署,我将要上传版本 02,然后是版本 03 等。Terraform 用新的预期行为替换旧的 zip .
但是有没有办法让 terraform 不破坏旧版本?这是这里受支持的用例还是这不是我应该使用 terraform 的方式?如果 terraform 没有官方支持做我在这里想做的事情,我不想用一个丑陋的 hack 来强迫它。
我当然可以通过脚本调用 S3 api,但最好能将其与此应用程序的其余 terraform 定义一起定义。
目前,您告诉 terraform 管理一个 aws_s3_bucket_object
并且 terraform 负责它的整个生命周期,这意味着 terraform 也会在发现任何更改时替换该文件。
您可能正在寻找的是 null_resource. You can use it to run a local-exec 配置器,它可以使用脚本上传您需要的文件。这样,旧文件就不会被删除,因为它不是由 terraform 直接管理的。您仍然会通过脚本调用 API,但上传到 s3 的整个过程仍将包含在您的 terraform apply
步骤中。
这里是null_resource
的大纲:
resource "null_resource" "upload_to_s3" {
depends_on = ["<any resource that should already be created before upload>"]
...
triggers = ["<A resource change that must have happened so terraform starts the upload>"]
provisioner "local-exec" {
command = "<command to upload local package to s3>"
}
}
在使用 Terraform 进行应用程序部署时,推荐的方法是将构建步骤与部署步骤分开,仅对后者使用 Terraform。
构建步骤——使用单独的工具实现,具体取决于部署方法——的职责是生成一些工件(存档、docker 容器、虚拟机映像等),将其发布到某处,然后将其位置或标识符传递给 Terraform 进行部署。
构建和部署之间的这种分离允许更复杂的情况,例如如果新版本有问题回滚到旧工件(而不重建它)。
在简单的场景中,可以使用 Input Variables 将工件位置传递给 Terraform。例如,在构建过程将 zip 文件写入 S3 的情况下,您可以定义如下变量:
variable "archive_name" {
}
然后可以使用 ${var.archive_name}
插值语法将其传递给任何需要它的资源。要部署特定工件,请使用 -var
:
$ terraform apply -var="archive_name=version01.zip"
一些组织喜欢在某种数据存储中记录每个应用程序的 "current" 版本,例如 HashiCorp Consul, and read it using a data source。这种方法可以更容易地在自动构建管道中进行编排,因为它允许使用这个单独的数据存储在构建和部署步骤之间间接传递存档名称,而无需将任何不寻常的参数传递给 Terraform 本身。