有没有办法在不必在局部变量中创建新变量的情况下进行嵌套 for 循环?
Is there a way to have a nested for loop without having to create a new variable in locals?
在 terraform v0.14.4 上
我的变量如下所示:
variable "my_config" {
type = object({
instances = set(string)
locations = set(string)
})
default = {
locations = [
"us",
"asia"
]
instances = [
"instance1",
"instance2"
]
}
我想遍历资源中的这个 var 并为每个位置 + 实例创建一个资源实例。资源的“名称”字段也将是 "<LOCATION>_<INSTANCE>"
。
我可以在 locals 中创建一个新的 var 来读取 my_config var 并生成一个新的 var,如下所示:
[
"us_instance1",
"us_instance2",
"asia_instance1",
"asia_instance2",
]
不过,我宁愿不从这个现有的 var 生成新的 terraform var。是否可以在 foreach 循环中直接在资源定义中聚合这两个列表?或者是在本地创建新数据结构的唯一方法?
编辑
我无法获得在资源定义中工作所提供的答案中的展平示例。我收到此错误:The given "for_each" argument value is unsuitable: the "for_each" argument must be a map, or set of strings, and you have provided a value of type tuple.
如果类型为 set(string)
或 list(string)
,则会发生此错误。
# This works
output "test" {
value = flatten(
[
for location in var.my_config.locations : [
for instance in var.my_config.instances : "${location}_${instance}"
]
]
)
}
# This throws the error
resource "null_resource" "test" {
for_each = flatten(
[
for location in var.my_config.locations : [
for instance in var.my_config.instances : "${location}_${instance}"
]
]
)
provisioner "local-exec" {
command = "echo test"
}
}
实现return值:
[
"us_instance1",
"us_instance2",
"asia_instance1",
"asia_instance2",
]
通过输入变量 my_config
,您可以:
flatten([for location in var.my_config.locations : [
for instance in var.my_config.instances : "${location}_${instance}"
]])
是否在 locals
块中定义它取决于您。如果您多次计划 re-using 这个值,那么将它定义为 local
会更有效。如果您打算只使用它一次,那么不在 locals
.
中定义它肯定更有意义
请注意,这还假定 my_config
类型为 object(list(string))
。问题中没有给出类型,但如果类型不是,那么代码会变得更加模糊。
关于在资源范围内将此值用作 for_each
meta-argument 值的其他问题,需要将其转换为类型 set(string)
。这可以使用 toset
函数轻松完成:
resource "resource" "this" {
for_each = toset(<expression above or variable with return value of above assigned to it>)
}
在 terraform v0.14.4 上
我的变量如下所示:
variable "my_config" {
type = object({
instances = set(string)
locations = set(string)
})
default = {
locations = [
"us",
"asia"
]
instances = [
"instance1",
"instance2"
]
}
我想遍历资源中的这个 var 并为每个位置 + 实例创建一个资源实例。资源的“名称”字段也将是 "<LOCATION>_<INSTANCE>"
。
我可以在 locals 中创建一个新的 var 来读取 my_config var 并生成一个新的 var,如下所示:
[
"us_instance1",
"us_instance2",
"asia_instance1",
"asia_instance2",
]
不过,我宁愿不从这个现有的 var 生成新的 terraform var。是否可以在 foreach 循环中直接在资源定义中聚合这两个列表?或者是在本地创建新数据结构的唯一方法?
编辑
我无法获得在资源定义中工作所提供的答案中的展平示例。我收到此错误:The given "for_each" argument value is unsuitable: the "for_each" argument must be a map, or set of strings, and you have provided a value of type tuple.
如果类型为 set(string)
或 list(string)
,则会发生此错误。
# This works
output "test" {
value = flatten(
[
for location in var.my_config.locations : [
for instance in var.my_config.instances : "${location}_${instance}"
]
]
)
}
# This throws the error
resource "null_resource" "test" {
for_each = flatten(
[
for location in var.my_config.locations : [
for instance in var.my_config.instances : "${location}_${instance}"
]
]
)
provisioner "local-exec" {
command = "echo test"
}
}
实现return值:
[
"us_instance1",
"us_instance2",
"asia_instance1",
"asia_instance2",
]
通过输入变量 my_config
,您可以:
flatten([for location in var.my_config.locations : [
for instance in var.my_config.instances : "${location}_${instance}"
]])
是否在 locals
块中定义它取决于您。如果您多次计划 re-using 这个值,那么将它定义为 local
会更有效。如果您打算只使用它一次,那么不在 locals
.
请注意,这还假定 my_config
类型为 object(list(string))
。问题中没有给出类型,但如果类型不是,那么代码会变得更加模糊。
关于在资源范围内将此值用作 for_each
meta-argument 值的其他问题,需要将其转换为类型 set(string)
。这可以使用 toset
函数轻松完成:
resource "resource" "this" {
for_each = toset(<expression above or variable with return value of above assigned to it>)
}