Terraform:在创建块内引用本地值

Terraform: Reference locals values inside the creation block

是否可以在创建本地值时引用另一个本地值?

下面的例子是我能想到的最小最简单的例子。

variable "size" {
  default     = 3
}

variable "infrastructure_version" {
  default = 1
}

locals {
  values = {
    for n in range(var.size) : n => {
      name = "instance_${n + 1}"
      full_name = "test_${name}_v${var.infrastructure_version}"
    }
  }
}

当尝试在本地块内的 for 循环中访问 name 时,出现以下错误:

│ Error: Invalid reference
│ 
│   on instances.tf line 13, in locals:
│   13:       full_name = "test_${name}_v${var.infrastructure_version}"
│ 
│ A reference to a resource type must be followed by at least one attribute access, specifying the resource name.

其他尝试: (这些都是绝望的尝试,没有真正成功的可能性)

有人知道这是否可行吗?或者我是否还在 full_name 中重复创建 name

full_name = "test_instance_${n + 1}_v${var.infrastructure_version}"

你最后一次尝试是正确的。你不能让它与众不同而且它有效:

 full_name = "test_instance_${n + 1}_v${var.infrastructure_version}"

不必在每次使用值时都进行变量插值,而是可以创建一个充当函数的本地模块。 您可以在哪里使用局部变量并重用以前创建的变量。

下面的简短示例,由于开销较大,它更适合用于更复杂和更大的应用程序。

main.tf: 我从主模块导入将用作函数的本地模块

module "instance_conf" {
  source = "./modules"
  count  = var.size

  index = count.index
  infra = var.infrastructure_version
}

locals {
  values = {for idx, val in module.instance_conf: idx => val}  
}

我将索引和基础设施作为输入发送到模块。其他模块中的变量定义必须与之匹配,如果需要,您也可以在这里提供描述。

modules/func.tf:

variable "index" {
  type = number
}

variable "infra" {
  type = number
}

locals {
  name = "instance_${var.index + 1}"
}

output "name" {
  value = local.name
}
output "full_name" {
  value = "test_${local.name}_v${var.infra}"
}

要获得主模块所需的输出,请在本地块或直接在输出块中计算值。导入此模块时,对于主模块中的每个 count.index,值将作为映射列表提供。 count = var.size

列表可能如下所示:

[
  {
    name: "instance_1",
    full_name: "test_instance_1_v1"
  },
  {
    name: "instance_2",
    full_name: "test_instance_2_v1"
  },
  ...
]

所以为了像以前一样使用模块输出for_each,我将地图对象列表转换为一个地图,其中每个地图对象的索引作为该对象的键。

locals {
  values = {for idx, val in module.instance_conf: idx => val}  
}

现在使用 local.values 时,它看起来像这样:

{
  "1": {
    name: "instance_1",
    full_name: "test_instance_1_v1"
  },
  "2": {
    name: "instance_2",
    full_name: "test_instance_2_v1"
  },
  ...
}

项目结构现在如下所示:

.
├── main.tf
├── modules
│   └── values_function.tf

希望这可以帮助其他人。当每次使用变量插值和重新创建一个值时,这不是一个可接受的答案。主要是因为可维护性因素。