如何在Terraform中对列表(对象)变量执行嵌套for循环



我正在编写一个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
}))
}))
}

Terraform输出

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接受map或set,因此您必须将对象数组转换为map。常见的方法是先创建对象的平面阵列,然后将其转换为贴图。它可以通过使用压平函数来完成。为了更好的可读性,我把它放在一个局部变量中,但它也可以内联完成:

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
}

最新更新