Terraform合并两个结构相同的列表



需要帮助:如何合并两个相同的应用程序-id&同一应用程序的值[App Role&Oauth scope]。

感谢您的帮助!!!

oauth_merge_permissions  = [
{
App1 = {
role1 = "729e1819-d582-d503-deff-2be33394cee5"
role2     = "fb9b9a2d-2653-ad21-556b-67b40742f4e1"
role3    = "f9dbd854-e42e-298e-c7d6-ba068d67261d"
role4   = "5324f064-ac54-db19-16c0-0510a3b979dc"
role5  = "d1577294-3870-e465-c433-e036bd2d624c"
role6     = "c13d1bc7-ffc2-dd8c-001e-c42c7c1b32cc"
}
},
{
App1 = {
test               = "da2a01d8-9865-412b-b7ef-f48f1e56e481"
user_impersonation = "7b31ca60-1333-4620-9582-012f25f4da05"
}
},
{
App2 = {
role5  = "d1577294-3870-e465-c433-e036bd2d624c"
role6     = "c13d1bc7-ffc2-dd8c-001e-c42c7c1b32cc"
}
}
]

期望输出:我会得到下面的输出,这样我就可以在azured_application API权限中使用这个输出。

Result = [
{
App1 = {
role1 = "729e1819-d582-d503-deff-2be33394cee5"
role2     = "fb9b9a2d-2653-ad21-556b-67b40742f4e1"
role3    = "f9dbd854-e42e-298e-c7d6-ba068d67261d"
role4   = "5324f064-ac54-db19-16c0-0510a3b979dc"
role5  = "d1577294-3870-e465-c433-e036bd2d624c"
role6     = "c13d1bc7-ffc2-dd8c-001e-c42c7c1b32cc"
test               = "70efda02-14a2-48f2-9297-8d86e7737438"
user_impersonation = "e100b04b-fb46-b764-8ae9-513e1f1cd469"
}
},       
{
App2 = {
role5  = "d1577294-3870-e465-c433-e036bd2d624c"
role6     = "7b31ca60-1333-4620-9582-012f25f4da05"
}
}
]

我认为要做到这一点需要两个步骤:首先按应用程序名称将对象聚集在一起,然后在这些组中将对象合并在一起。

让我们从第一步开始:

locals {
oauth_merge_permissions = [
{
App1 = {
role1 = "729e1819-d582-d503-deff-2be33394cee5"
role2 = "fb9b9a2d-2653-ad21-556b-67b40742f4e1"
role3 = "f9dbd854-e42e-298e-c7d6-ba068d67261d"
role4 = "5324f064-ac54-db19-16c0-0510a3b979dc"
role5 = "d1577294-3870-e465-c433-e036bd2d624c"
role6 = "c13d1bc7-ffc2-dd8c-001e-c42c7c1b32cc"
}
},
{
App1 = {
test               = "da2a01d8-9865-412b-b7ef-f48f1e56e481"
user_impersonation = "7b31ca60-1333-4620-9582-012f25f4da05"
}
},
{
App2 = {
role5 = "d1577294-3870-e465-c433-e036bd2d624c"
role6 = "c13d1bc7-ffc2-dd8c-001e-c42c7c1b32cc"
}
}
]
role_maps_by_app = {
for m in local.oauth_merge_permissions : one(keys(m)) => one(values(m))...
}
}

objects_by_app的值如下,输入如下所示:

role_maps_by_app = {
"App1" = [
{
"role1" = "729e1819-d582-d503-deff-2be33394cee5"
"role2" = "fb9b9a2d-2653-ad21-556b-67b40742f4e1"
"role3" = "f9dbd854-e42e-298e-c7d6-ba068d67261d"
"role4" = "5324f064-ac54-db19-16c0-0510a3b979dc"
"role5" = "d1577294-3870-e465-c433-e036bd2d624c"
"role6" = "c13d1bc7-ffc2-dd8c-001e-c42c7c1b32cc"
},
{
"test"               = "da2a01d8-9865-412b-b7ef-f48f1e56e481"
"user_impersonation" = "7b31ca60-1333-4620-9582-012f25f4da05"
},
]
"App2" = [
{
"role5" = "d1577294-3870-e465-c433-e036bd2d624c"
"role6" = "c13d1bc7-ffc2-dd8c-001e-c42c7c1b32cc"
},
]
}

我在这里做了两个假设:

  • 每个顶级映射中只有一个元素
  • 您使用的是Terraform v0.15.0或更高版本,因此可以使用one函数。如果没有,可以使用类似keys(m)[0]的表达式,唯一的区别是它将忽略映射中的多个元素,而不是引发错误

现在我们有了一个地图列表的地图,我们可以编写第二步,将每个列表中的所有地图合并为一个单独的地图:

locals {
# (keep the other local values from above too)
roles_by_app = {
for app, role_maps in local.role_maps_by_app : app => merge(role_maps...)
}  
}

local.roles_by_app将具有以下值,该值似乎符合您的要求:

roles_by_app = {
"App1" = {
"role1"              = "729e1819-d582-d503-deff-2be33394cee5"
"role2"              = "fb9b9a2d-2653-ad21-556b-67b40742f4e1"
"role3"              = "f9dbd854-e42e-298e-c7d6-ba068d67261d"
"role4"              = "5324f064-ac54-db19-16c0-0510a3b979dc"
"role5"              = "d1577294-3870-e465-c433-e036bd2d624c"
"role6"              = "c13d1bc7-ffc2-dd8c-001e-c42c7c1b32cc"
"test"               = "da2a01d8-9865-412b-b7ef-f48f1e56e481"
"user_impersonation" = "7b31ca60-1333-4620-9582-012f25f4da05"
}
"App2" = {
"role5" = "d1577294-3870-e465-c433-e036bd2d624c"
"role6" = "c13d1bc7-ffc2-dd8c-001e-c42c7c1b32cc"
}
}

在第二步中,我使用了merge函数,它将许多映射作为参数,并返回一个映射,其中所有元素都通过键合并在一起。因为merge需要可变数量的参数,而不是列表中的单个参数,所以我在role_maps参数上使用了...修饰符来告诉Terraform将该列表中的每个元素用作函数的单独参数。

最新更新