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.
其他尝试:
(这些都是绝望的尝试,没有真正成功的可能性)
local.values[n].name
给出 Error: Self-referencing local value
n.name
给出 Error: Unsupported attribute
self.name
给出 Error: Invalid "self" reference
有人知道这是否可行吗?或者我是否还在 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
希望这可以帮助其他人。当每次使用变量插值和重新创建一个值时,这不是一个可接受的答案。主要是因为可维护性因素。
是否可以在创建本地值时引用另一个本地值?
下面的例子是我能想到的最小最简单的例子。
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.
其他尝试: (这些都是绝望的尝试,没有真正成功的可能性)
local.values[n].name
给出Error: Self-referencing local value
n.name
给出Error: Unsupported attribute
self.name
给出Error: Invalid "self" reference
有人知道这是否可行吗?或者我是否还在 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
希望这可以帮助其他人。当每次使用变量插值和重新创建一个值时,这不是一个可接受的答案。主要是因为可维护性因素。