如何在 Terraform 中对列表(对象)变量执行嵌套循环
How perform nested for loop on list(object) variable in Terraform
我正在编写一个 terraform 模块接受 list
个实体,每个 entity
与一个别名列表相关联。我在访问别名对象并传入 each.key
时遇到问题。非常感谢任何帮助。
resource "vault_identity_entity_alias" "alias" {
provider = vault.this
for_each = [
for entity in var.entities : {
for alias in entity.aliases :
alias.name => alias
}
]
name = each.key
mount_accessor = lookup(vault_auth_backend.b[each.key], "accessor", null)
canonical_id = vault_identity_entity.entity[each.value.entity].id
}
变量定义
variable "entities" {
description = "A collection of entities where each entity is associated with a list aliases "
type = list(object({
name = string
policies = list(string)
metadata = map(string)
aliases = list(object({
name = string
entity = string
auth_path = string
type = string
}))
}))
}
地形输出
Error: Invalid for_each argument
on .terraform/modules/vault_dba_entity/main.tf line 9, in resource "vault_auth_backend" "b":
9: for_each = [
10: for entity in var.entities : {
11: for alias in entity.aliases :
12: alias.name => alias
13: }
14: ]
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.
如错误消息所述,for_each
接受映射或集合,因此您必须将对象数组转换为映射。常见的做法是先创建平面对象数组,然后将其转换为地图。可以使用 flatten 函数来完成。为了更好的可读性,我把它放在一个局部变量中,但它也可以内联完成:
locals {
entities = flatten([
for entity in var.entities: [
for alias in entity.aliases: {
entity_name = entity.name
alias_name = alias.name
alias_entity = alias.entity
}
]
])
}
变量 local.entities
将包含对象列表,例如:
[
{
"alias_name" = "alias1"
"entity_name" = "object1"
"alias_entity" = "entity alias1"
},
{
"alias_name" = "alias2"
"entity_name" = "object1"
"alias_entity" = "entity alias2"
},
]
现在很容易将其转换为地图。我们只需要选择唯一键用作索引。根据你的问题,别名应该是唯一的,所以可以这样做:
resource "vault_identity_entity_alias" "alias" {
provider = vault.this
for_each = {
for item in local.entities: item.alias_name => item
}
name = each.key
mount_accessor = lookup(vault_auth_backend.b[each.key], "accessor", null)
# Note, we reference alias_entity, because it was defined with this name
# in local variable.
canonical_id = vault_identity_entity.entity[each.value.alias_entity].id
}
我正在编写一个 terraform 模块接受 list
个实体,每个 entity
与一个别名列表相关联。我在访问别名对象并传入 each.key
时遇到问题。非常感谢任何帮助。
resource "vault_identity_entity_alias" "alias" {
provider = vault.this
for_each = [
for entity in var.entities : {
for alias in entity.aliases :
alias.name => alias
}
]
name = each.key
mount_accessor = lookup(vault_auth_backend.b[each.key], "accessor", null)
canonical_id = vault_identity_entity.entity[each.value.entity].id
}
变量定义
variable "entities" {
description = "A collection of entities where each entity is associated with a list aliases "
type = list(object({
name = string
policies = list(string)
metadata = map(string)
aliases = list(object({
name = string
entity = string
auth_path = string
type = string
}))
}))
}
地形输出
Error: Invalid for_each argument
on .terraform/modules/vault_dba_entity/main.tf line 9, in resource "vault_auth_backend" "b":
9: for_each = [
10: for entity in var.entities : {
11: for alias in entity.aliases :
12: alias.name => alias
13: }
14: ]
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.
如错误消息所述,for_each
接受映射或集合,因此您必须将对象数组转换为映射。常见的做法是先创建平面对象数组,然后将其转换为地图。可以使用 flatten 函数来完成。为了更好的可读性,我把它放在一个局部变量中,但它也可以内联完成:
locals {
entities = flatten([
for entity in var.entities: [
for alias in entity.aliases: {
entity_name = entity.name
alias_name = alias.name
alias_entity = alias.entity
}
]
])
}
变量 local.entities
将包含对象列表,例如:
[
{
"alias_name" = "alias1"
"entity_name" = "object1"
"alias_entity" = "entity alias1"
},
{
"alias_name" = "alias2"
"entity_name" = "object1"
"alias_entity" = "entity alias2"
},
]
现在很容易将其转换为地图。我们只需要选择唯一键用作索引。根据你的问题,别名应该是唯一的,所以可以这样做:
resource "vault_identity_entity_alias" "alias" {
provider = vault.this
for_each = {
for item in local.entities: item.alias_name => item
}
name = each.key
mount_accessor = lookup(vault_auth_backend.b[each.key], "accessor", null)
# Note, we reference alias_entity, because it was defined with this name
# in local variable.
canonical_id = vault_identity_entity.entity[each.value.alias_entity].id
}