Terraform中变量嵌套变量

59

首先,对不起 - 我非常新手(只有3个小时!)使用terraform。

我想尝试在另一个变量的声明中使用变量的值。

以下是我的代码 - 我做错了什么?

variables.tf:

variable "EnvironmentName" {
    type = "string"
}
variable "tags" {
    type = "map"
    default = {
        Environment = "${var.EnvironmentName}"
        CostCentre = "C1234"
        Project = "TerraformTest"
        Department = "Systems"
    }
}

变量-dev.tfvars:

EnvShortName = "Dev"
EnvironmentName = "Development1"
#Location
Location = "westeurope"

main.tf:

resource “azurerm_resource_group” “TestAppRG” {
    name = “EUW-RGs-${var.EnvShortName}”
    location = “${var.Location}”
    tags = “${var.tags}”
}

我遇到了以下错误:

Error: Variables not allowed on variables.tf line 18, in variable
“tags”: 18: Environment = “${var.EnvironmentName}”
在此处不允许使用变量。

我知道这个错误信息本身已经很清楚了,很可能是我的方法有误——但我该如何在定义另一个变量映射时使用变量呢?这是否可能?

我将建立多个资源,因此希望将标记构建为一个映射,并将其传递到每个资源中,但我还想通过其他tfvars文件循环使用该映射以部署多个实例供不同团队使用。


使用var内的var有几种方法-1.使用lookup 2.与var一起使用本地,请参阅-https://jhooq.com/terraform-var-within-var/ - Rahul Wagh
3个回答

68

Terraform不支持在变量中使用变量。如果您想基于两个或更多变量生成值,则可以尝试Terraform locals

您可以像这样定义locals

locals {
  tags = {
    Environment = "${var.EnvironmentName}"
    CostCentre  = "C1234"
    Project     = "TerraformTest"
    Department  = "Systems"
  }
}

然后您可以使用local.tags来访问它们:

resource “azurerm_resource_group” “TestAppRG” {
  name     = “EUW-RGs-${var.EnvShortName}”
  location = “${var.Location}”
  tags     = “${local.tags}”
}

1
但我们需要在每个模块中定义这个,如果我必须为整个平台实现并且我有不同的资源模块,那么我应该在每个模块的 main.tf 文件中创建这个吗? - s_k_t
您可以在根模块中引用多个模块,并且在根模块中(运行terraform apply的位置)可以设置本地变量。请查看我存储库中的此示例:https://github.com/pgreene/terraform-aws-rds-cluster-plan Terraform将所有*.tf文件视为一个文件。因此,如何组织它们取决于您。您可以看到,locals.tf在main.tf中的多个资源(模块)中被引用。 - paulg
如果我需要在本地变量中访问一个包含地图的变量,例如format("%s-subnet", var.environment)["address"],会出现无效索引的情况,因为变量只有在应用后才能知道。在这种情况下,是否可以使用输出变量或显式依赖项? - tuxErrante
你的意思是访问 locals 中的 map 类型变量吗?一种方法是这样的 - format("%s-webserver", var.labels["environment"]) 假设你有一个映射变量 labels = { "environment" = "dev" "team" = "devops" "application" = "webserver" } ,那么你可以在 locals 中像这样使用它 locals { name = format("%s-webserver", var.labels["environment"]) } - Pradeep Bhadani

5
你需要使用本地变量来完成你想要的转换排序。 variables.tf:
variable "EnvironmentName" {
    type = "string"
}

locals.tf

locals {
  tags = {
      Environment = var.EnvironmentName
      CostCentre = "C1234"
      Project = "TerraformTest"
      Department = "Systems"
  }
}

Variables-dev.tfvars:

EnvShortName = "Dev"
EnvironmentName = "Development1"
#Location
Location = "westeurope"

main.tf:

resource “azurerm_resource_group” “TestAppRG” {
    name = “EUW-RGs-${var.EnvShortName}location = var.Location
    tags = local.tags
}

你可以使用 `tags = merge(local.tags,{"key"="value"})` 来扩展标签。

0
除了这个问题之外,通常会有一个谷歌请求类似问题的问题,关于如何“基于另一个变量改变局部值”,这里有一个有用且相关的方法,可以用于这样的请求。
在某些情况下,当你有一个无法更改的常量变量(比如说var.env),并且你需要根据该变量的值来确定另一个局部值是0还是1,那么你需要根据另一个值进行切换。为了实现这一点,请按照以下步骤进行操作:
env_prefix = var.env == "dev" ? "np" : "pd"

在这种情况下,如果var.env的值等于dev,那么env_prefix将是np。否则,env_prefix将是pd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接