I’d like to use that in the google_project_iam_member resource. For that, I think I should achieve something like that so I can use for_each within it:
Here’s something that I think does what you’re looking for:
locals {
gcp_sa_roles = [
{
project_id = "test_project1"
roles = [
"a",
"b"
]
},
{
project_id = "test_project2"
roles = [
"a",
"c"
]
}
]
project_roles = {
for gsr in local.gcp_sa_roles: gsr.project_id => gsr.roles
}
project_role_maps = [
for project, roles in local.project_roles: {
for role in roles: "${project}.${role}" => [project, role]
}
]
result = merge(local.project_role_maps...)
}
This makes use of the ... argument expansion operator, and uses several intermediate steps to make debugging easier. It can be collapsed into one expression if that’s clearer to you:
result = merge([
for project, roles in { for gsr in local.gcp_sa_roles: gsr.project_id => gsr.roles }: {
for role in roles: "${project}.${role}" => [project, role]
}
]...)
I ended up using the following to generate something usable to the for_each:
locals {
all_gcp_sa_roles = flatten([
for permission in var.gcp_sa_roles :
[for role in permission.roles : { project_id = permission.project_id, role = role }]
])
}
The local.all_gcp_sa_roles has the following output (as example):
That way, I can use the for_each to iterate over the all_gcp_sa_roles:
resource "google_project_iam_member" "workload_identity_sa_bindings" {
for_each = { for role in local.all_gcp_sa_roles : "${role.project_id}.${role.role}" => role }
project = each.value.project_id
role = each.value.role
member = "serviceAccount:${google_service_account.cluster_service_account.email}"
}