问题描述
我正在编写一个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
接受map或set,因此必须将对象数组转换为map。常用的方法是先创建对象的平面数组,然后将其转换为地图。可以使用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
}