问题描述
我有这样的事情
locals {
roles = [
{
role = "roles/admin"
members = ["user:[email protected]"]
},
{
role = "roles/viewer"
members = ["user:[email protected]"]
}
]
}
我希望我的模块能够导出自己的角色列表,例如
I want my modules to be able to export their own list of roles like
roles = [
{
role = "roles/viewer"
members = ["user:[email protected]"]
}
]
然后能够将这些东西合并在一起得到
And then be able to merge these things together to get
locals {
roles = [
{
role = "roles/admin"
members = ["user:[email protected]"]
},
{
role = "roles/viewer"
members = ["user:[email protected]", "user:[email protected]"]
}
]
}
我知道如果我将所有内容都存储为地图,我可以合并地图,只要没有重复的键,它就可以正常工作.但在这种情况下,我明确希望能够拥有重复的键,这样一个模块就不需要关心任何其他模块.
I know if I stored everything as maps I could merge the maps and it would work fine as long as there are no duplicate keys. But in this case I explicitly want to be able to have duplicate keys so that one module doesn't need to care about any of the other modules.
更新我能够通过这样做来实现这一点:
Update I was able to achieve this by doing something like so:
roles = distinct(flatten([
for rm in local.role_maps : [
for role, members in rm :
{
role = role
members = sort(distinct(flatten([
for m in local.role_maps :
m[role] if lookup(m, role, null) != null
])))
}
]
]))
推荐答案
这似乎是一个很好的for
表达式 使用 ...
分组修饰符,它可以通过键分组生成列表映射.
This seems like a good application for a for
expression using the ...
grouping modifier, which can produce a map of lists by grouping by the keys.
variable "custom_roles" {
type = list(object({
role = string
members = list(string)
})
}
locals {
default_roles = [
{
role = "roles/admin"
members = ["user:[email protected]"]
},
{
role = "roles/viewer"
members = ["user:[email protected]"]
}
]
all_roles = concat(
local.default_roles,
var.custom_roles,
)
# First we'll project the inputs so that we have one
# role/member pair per element.
flat_roles = flatten([
for r in locals.all_roles : [
for m in r.members : {
role = r.role
member = m
}
]
])
# Then we can use that flattened list to produce a map
# grouped by unique role key.
merged_roles = {
for k, v in local.all_roles : k => v...
}
# Finally, if the list-of-objects representation was
# important then we can recover it by projecting that
# merged_roles map back into the list shape.
merged_roles_list = tolist([
for role, members in local.merged_roles : {
role = role
members = tolist(members)
}
])
}
在上面,local.merged_roles
是列表的映射,如下所示:
In the above, local.merged_roles
is a map of lists, like this:
{
"roles/admin" = ["user:[email protected]"]
"roles/viewer" = ["user:[email protected]", "user:[email protected]"]
}
您可以直接使用该地图,但为了以防对象列表表单很重要,我包含了 local.merged_roles_list
,它应该与您提出的问题的结构相匹配.
You could potentially use that map directly, but just in case the list-of-objects form was important I included local.merged_roles_list
which should match the structure you asked for your question.
这篇关于Terraform:合并列表的映射并合并来自重复键的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!