我试着在Terraform工作区中走过荆棘丛生的道路
这篇文章是2023年3-shake附赠产品系列2的第14天的内容。
几乎完全出于兴趣,我尝试使用terraform工作区开始了一段旅程,但却遇到了许多棘手的问题…
这是一个这样的故事。
背景 – 在中国需要的只是一个选项
在某项工作中,我决定使用AWS进行基础架构的搭建。一开始我打算像往常一样使用Terraform,但突然想起了工作空间的存在。由于我之前没有经验,并且也有些兴趣,所以我决定尝试采用工作空间的方式。
-
- そこまで大きな規模でもなく、
-
- 環境間の差分もあまりなさそうだったため
- 何より使ったことないから試してみようっていう好奇心97%
在这个话题中,前提是要吸收不同环境之间的差异。
有关Terraform工作空间的信息。
“面”作为工作空间进行管理,可以在同一代码库中管理多个面的机制。
针对这些多个面,将创建对应的tfstate文件作为后端。
terraform workspace -h
Usage: terraform [global options] workspace
new, list, show, select and delete Terraform workspaces.
Subcommands:
delete Delete a workspace
list List Workspaces
new Create a new workspace
select Select a workspace
show Show the name of the current workspace
首先,让我们创建一个工作区。
terraform workspace new prd
terraform workspace new stg
terraform workspace new dev
terraform workspace list
default
dev
prd
stg
切换工作区。
bucket = "stg-tf"
region = "ap-northeast-1"
key = "inf.tfstate"
encrypt = true
shared_credentials_file = "[$HOME/.aws/credentials]"
profile = "stg"
选择工作区并初始化。
terraform workspace select stg
terraform init -reconfigure -backend-config=backends/stg.tfbackend
嗯,怎么样?
太让人伤心了。
Q: 你为什么觉得辛苦?
A: 不适用于该使用场景
一开始听说时,认为环境差异并不大,计划是制作一个版本然后复制扩散。但是,实际上不同环境下基础设施的管理范围有所不同,或者简单地说,会出现“这个环境需要这个”的情况。
在公式中有以下的注释。
特别是,组织通常希望在为不同的开发阶段或不同的内部团队服务的同一基础架构的多个部署之间建立强大的分离。在这种情况下,每个部署的后端通常具有不同的凭据和访问控制。工作目录中的CLI工作区使用相同的后端,因此对于这种情况,它们不是合适的隔离机制。
简而言之,这种方式不适用于管理开发阶段不同的环境,如dev / stg / prd。
作为常见的用例,以下是逆向的例子。
使用多个工作区的常见用途是在修改生产基础设施之前,创建一组平行且独立的基础设施副本,以测试一组变更。
创建多个相同环境,作为改变生产环境之前的测试副本。
他毅然向前,就像踢开茨丛般坚定地走在崎岖的道路上。
我将根据自身的经历,以一个完全相悖于上述观点的反例来说明什么样的点是不适合的。
编码变得复杂
因此,在变量中将workspace名作为资源的存在表示,因此有这样的描述。
resource "aws_lb" "alb" {
name = var.name
load_balancer_type = "application"
internal = var.enable_internal
idle_timeout = 60
enable_deletion_protection = (
terraform.workspace == "infra-dev" ? false :
terraform.workspace == "dev" ? false : true
)
在进行成本优化时,根据不同环境来调整实例的大小、数量以及使用SPOT实例等等,对吧?
每次环境的差异增加,会导致这种记法大量出现。
无法像 dev -> stg -> prd那样按顺序进行环境演进进行版本升级
使用Terraform意味着需要更新Core和Provider的版本,对吗?基本上,我认为会按照上述方式逐步执行环境追踪。
我认为可以重写以下terraform块的required_version,然后再进行init,根据需要进行修正,最后解决差异并应用。
terraform {
required_version = "1.3.5"
backend "s3" {
}
required_providers {
aws = "4.39.0"
kubernetes = {
source = "hashicorp/kubernetes"
version = ">=2.16.0"
}
tls = {
source = "hashicorp/tls"
version = ">= 3.0"
}
}
}
然而,无论是terraform块本身还是锁定文件,都不能根据不同的环境进行准备。
考虑到先前的常见用例,我确实同意这一点,感到很满意。
总结
用这种方式试用一下虽然有些困难,但也使我对这个workspace功能有了非常清晰的了解。总结在应用场景中的感想如下。
-
- dev / stg / prdのように環境差分を吸収するような一般的な目的で使うものではない
- 逆に複数人に全く同じ開発環境を払い出したり、本番前のテストapplyなどでは有用に感じる
虽然有些麻烦,但由于似乎可以稍后合并并迁移,我认为在Terraform的初始存储库架构中,假设首先切换工作目录没有问题。
希望您能够将这个作为每个使用案例的选择之一记在心里。
请从中找到灵感
- https://dev.classmethod.jp/articles/how-to-use-terraform-workspace/