我见过推荐使用 Terraform 工作区来管理不同的阶段(暂存、生产)。这似乎适用于大多数情况,因为您通常会创建名称中包含阶段/工作区的不同资源,或者,如果它是共享资源,您会将其导入到每个工作区状态中。
但是,我不确定该如何处理 API 网关。这种类型的资源无法在状态下导入,这意味着如果您在暂存中创建它,则必须将其删除并在生产中重新导入。
您如何处理阶段和 API 网关?
答案1
使用“count”和“splat 语法”。 “splat 语法”在变量前面是“*”。 (例如shared_resource.example.*.id
)使用此语法时,terraform 不会因 count:0 而使用未创建的资源而出现错误。 我觉得这就像一个错误。
例如
第一步,CI 作业使用development
工作区,然后创建共享资源。在以下示例中,创建了名为“example”的 aws_api_gateway_rest_api 资源。接下来,使用production
工作区,资源并未创建,但 terraform 读取了“aws_api_gateway_rest_api.example”的数据。
# this resource is created when using development workspace
resource "aws_api_gateway_rest_api" "example" {
count = "${terraform.workspace == "development" ? 1 : 0}"
name = "this is example"
}
data "aws_api_gateway_rest_api" "example" {
count = "${terraform.workspace == "production" ? 1 : 0}"
name = "this is example"
}
使用资源时,必须指定如下资源值。
resource "sample_resource" "example" {
rest_api_id = "${terraform.workspace == "production" ? join("", data.aws_api_gateway_rest_api.example.*.id) : join("", aws_api_gateway_rest_api.example.*.id)}"
}
答案2
首先,TFstate 应该存储在远程。多个后端可用的
Terraform 从一个名为“默认”的工作区开始。
设置S3作为后端backend.tf
terraform {
backend "s3" {
region = "eu-south-1"
bucket = "backend.terraform"
key = "state.tfstate"
}
}
建议启用状态文件的版本控制。将本地状态推送至S3
terraform state push
创建工作区
terraform workspace new dev
Created and switched to workspace 'dev'
terraform workspace new preprod
选择开发工作区:
terraform workspace select dev
现在,一旦你应用了terraform apply
你的 tfstate 文件,它将存储在S3
然后根据当前工作区调用变量
bucket = "${terraform.workspace == "prod" ? var.bucket_demo_prod : var.bucket_demo}"