随着我们使用AWS CloudFormation遇到了一些困难,我正在考虑将一些基础架构代码切换到Terraform。
让我举一个我想要达到的目标的例子。我有一个ECS集群,可以运行10多个不同的任务定义。每个任务定义都包含几乎相同的配置,为避免代码重复,我正在构建一个可重用的模块。
从我收集的数据来看,有3种主要的方法来构建terraform目录。
1:
project
├── modules
| ├─ ecs
| ├── main.tf
| ├── variables.tf
| ├── task
| ├── main.tf
| ├── variables.tf
|
|
└── env
| ├─── dev.tfvars
| ├─── prod.tfvars
| ├─── stage.tfvars
| ├─── 10+
|
|
|── main.tf
|── variable.tf
使用这种结构,我必须从env文件夹中获取变量,并用-var-files="env/dev.tfvars"
传递它,然后在我的main.tf中,我必须将该变量传递到modules / ecs / task / main .tf似乎很漫长,并且要采取很多步骤才能将变量添加到ecs / task / main.tf
2。
project
├── modules
| ├─ ecs
| ├── main.tf
| ├── variables.tf
| ├── task
| ├── main.tf
| ├── variables.tf
|
|
└── stage
| ├─── main.tf
| ├─── variable.tf
| ├─── stage.tfvars
|
└── dev
| ├─── main.tf
| ├─── variable.tf
| ├─── dev.tfvars
|
└── 10+
| ├─── main.tf
| ├─── variable.tf
| ├─── X.tfvars
如果希望将基于环境的变量应用于modules/ecs/task/main.tf
,则必须从main.tf
开始,例如在调用modules/ecs/main.tf
的阶段。然后通过/modules/ecs/main.tf
将其应用到/modules/ecs/task/main.tf
。
这种方法的问题还在于,每当我添加新模块时,都必须将其添加到所有不同环境的main.tf
中。3。
project
├── modules
| ├── ecs
| ├── main.tf
| ├── variables.tf
| ├── task
| ├── main.tf
| ├── variables.tf
|
|
|
|
|── main.tf
|── variable.tf
使用terraform工作区,我可以在modules / ecs / task / variables.tf中使用本地变量来确定要构建的环境。像这样:
modules/ecs/task.variables.tf
locals {
env="${terraform.workspace}"
masterAccountIDS = {
"default"="12121212"
"dev"="84848484"
}
masterAccountID="${lookup(local.masterAccountIDS, local.env)}"
}
但这需要每次我添加一个新环境时,我都要遍历所有variables.tf文件,并添加一个新条目,例如“ stage”。
我想不出一种方法,允许我不复制粘贴代码,或者在添加新环境时不插入新东西,或者将所有内容都放在一个位置,所以我可能只需要编辑一个文件。 / p>
答案 0 :(得分:0)
使用工作空间是目前最好的选择。我正在使用类似下面的方法来在一处管理所有变量-
defaults.tf -
/* DEFAULT VARIABLES */
locals {
tags = {
Project = "${var.project}"
Contact = "vivek@vivekyadav.me"
Requester = "Vivek"
Creator = "Vivek"
ManagedBy = "TF"
Environ = "${local.workspace["environ"]}"
}
}
locals {
meta = {
name_prefix = "hpy-${local.workspace["environ"]}-${local.workspace["project_name"]}"
account_id = "${local.workspace["account_id"]}"
region_name = "${local.workspace["region_name"]}"
}
}
/* CUSTOM VARIABLES - ENVIRONMENT SPECIFIC */
################ DEFAULT LOCALS - DEFINE ENV VARIABLES FOR APP #################
locals {
env = {
default = {
project_name = "${var.project}"
region_name = "${var.region}"
environ = "dev"
account_id = "356******001"
}
default_list = {
}
################ DEV LOCALS - DEFINE ENV VARIABLES FOR APP #################
dev = {
environ = "dev"
}
dev_list = {
}
################ UAT LOCALS - DEFINE ENV VARIABLES FOR APP #################
uat = {
environ = "uat"
}
uat_list = {
}
################ PREP LOCALS - DEFINE ENV VARIABLES FOR APP #################
prep = {
environ = "prep"
}
prep_list = {
}
################ PRD LOCALS - DEFINE ENV VARIABLES FOR APP #################
prod = {
environ = "prod"
account_id = "3621****8334"
}
prod_list = {
}
}
################ EXPORTING ENV/WORKSPACE VARIABLES FOR APP #################
workspace = "${merge(local.env["default"], local.env[terraform.workspace])}"
workspace_lists= "${merge(local.env["default_list"], local.env[format("%v_list",terraform.workspace)])}"
}
现在您可以在主定义中调用上述变量-
main.tf -
module "s3" {
source = "s3"
tags = "${local.tags}"
meta = "${local.meta}"
workspace = "${local.workspace}"
workspace_list = "${local.workspace_list}"
}
现在您可以在模块内调用定义的变量,如下所示-
"${var.workspace["environ"]}"
PS-这是一种解决方法,但确实像现在一样运作良好。 Terraform应该提供一些开箱即用的东西来管理它。