I'm trying to generate a map, from a map within a list.
locals {
account_assignments_test = [
{
principal_name = "CORP_SYSTEM_RO@hq.vw.ad",
account = "123456789012",
permission_set_name = "system-audit"
},
{
principal_name = "CORP_SYSTEM_RW@hq.vw.ad",
account = [ "234567890123", "345678901234" ]
permission_set_name = "system-admin"
}
]
account_assignment_map_test = {
for pn in local.account_assignments_test : format("%v-%v-%v", pn.account, pn.principal_name, pn.permission_set_name) => pn
}
}
output "account_assignment_map_test" {
value = local.account_assignment_map_test
}
The outputs is clean:
Outputs:
account_assignment_map_test = {
"123456789012-CORP_SYSTEM_RO@hq.vw.ad-system-audit" = {
"account" = "123456789012"
"permission_set_name" = "system-audit"
"principal_name" = "CORP_SYSTEM_RO@hq.vw.ad"
}
"[\"234567890123\",\"345678901234\"]-CORP_SYSTEM_RW@hq.vw.ad-system-admin" = {
"account" = [
"234567890123",
"345678901234",
]
"permission_set_name" = "system-admin"
"principal_name" = "CORP_SYSTEM_RW@hq.vw.ad"
}
}
I do not feel comfortable with flatten, but I try it out, the idea is to loop on account
first, then on principal_name
(not sure if it's good idea). I've try lot of thing but without success.
account_assignment_map_test = flatten([
for principal_name_key, principal_name in local.account_assignments_test: [
for account_key, account in principal_name.account : {
principal_name_key = principal_name
account_key = account
# permission_set_name_key = permission_set_name
}
]
])
But it doesn't work, i got the following message :
│ Error: Iteration over non-iterable value
│
│ on variables_locals.tf line 66, in locals:
│ 65: for principal_name_key, principal_name in local.account_assignments_test: [
│ 66: for account_key, account in principal_name.account : {
│ 67: principal_name_key = principal_name
│ 68: account_key = account
│ 69: # permission_set_name_key = permission_set_name
│ 70: }
│ 71: ]
│ ├────────────────
│ │ principal_name.account is "123456789012"
│
│ A value of type string cannot be used as the collection in a 'for' expression.
I would like to iterate on account list to get something like this
Outputs:
association_list = {
"123456789012-CORP_SYSTEM_RO@hq.vw.ad-system-audit" = {
"account" = "123456789012"
"permission_set_name" = "system-audit"
"principal_name" = "CORP_SYSTEM_RO@hq.vw.ad"
}
"234567890123-CORP_SYSTEM_RW@hq.vw.ad-system-admin" = {
"account" = "234567890123"
"permission_set_name" = "system-admin"
"principal_name" = "CORP_SYSTEM_RW@hq.vw.ad"
}
"345678901234-CORP_SYSTEM_RW@hq.vw.ad-system-admin" = {
"account" = "345678901234"
"permission_set_name" = "system-admin"
"principal_name" = "CORP_SYSTEM_RW@hq.vw.ad"
}
}
To run a for_each
from a ressource:
resource "aws_ssoadmin_account_assignment" "test" {
for_each = local.account_assignment_map_test
instance_arn = local.sso_instance_arn
permission_set_arn = aws_ssoadmin_permission_set.test[each.value.permission_set_name].arn
principal_id = data.aws_identitystore_group.test[each.value.principal_name].id
principal_type = "GROUP"
target_id = each.value.account
target_type = "AWS_ACCOUNT"
}
I think that I need a nested loop to solve it, but i don't know how.
And i would like to know if it's permit to go further with a new iteration but on permission_set_name
:
{
principal_name = "CORP_SYSTEM_RW@hq.vw.ad",
account = [ "234567890123", "345678901234" ]
permission_set_name = ["system-admin", "system-admin"]
}
But, I'm note sure that we can iterate infinitely ?
Personally I am not a fan of this type of stuff in terraform. Its meant to be a configuration language not a programming language. I prefer simple expressions. If they start to get overly complicated then to me it normally indicates an issue with the general data structure of the input. However based on your question and expected output.
terraform {
}
locals {
account_assignments_test = [
{
principal_name = "CORP_SYSTEM_RO@hq.vw.ad",
account = "123456789012",
permission_set_name = "emobg-sso-system-audit"
},
{
principal_name = "CORP_SYSTEM_RW@hq.vw.ad",
account = ["234567890123", "345678901234"]
permission_set_name = "emobg-sso-system-admin"
}
]
account_assignment_map_test = merge([
for pn in local.account_assignments_test : {
for account in try(tolist(pn["account"]), [pn["account"]]) :
join("-", [account, pn["principal_name"], pn["permission_set_name"]]) =>
{ account = account, permission_set_name = pn["permission_set_name"], principal_name = pn["principal_name"] }
}
]...)
}
output "account_assignment_map_test" {
value = local.account_assignment_map_test
}
OUTPUT
Outputs:
account_assignment_map_test = {
"123456789012-CORP_SYSTEM_RO@hq.vw.ad-emobg-sso-system-audit" = {
"account" = "123456789012"
"permission_set_name" = "emobg-sso-system-audit"
"principal_name" = "CORP_SYSTEM_RO@hq.vw.ad"
}
"234567890123-CORP_SYSTEM_RW@hq.vw.ad-emobg-sso-system-admin" = {
"account" = "234567890123"
"permission_set_name" = "emobg-sso-system-admin"
"principal_name" = "CORP_SYSTEM_RW@hq.vw.ad"
}
"345678901234-CORP_SYSTEM_RW@hq.vw.ad-emobg-sso-system-admin" = {
"account" = "345678901234"
"permission_set_name" = "emobg-sso-system-admin"
"principal_name" = "CORP_SYSTEM_RW@hq.vw.ad"
}
}