I’m having some difficulty getting the flatten function to work. Hoping somebody can point me in the right direction.
Testing in Terraform console I have the following output:
> {
> "mfa" = [
> "admin",
> "super_admin",
> "user",
> ]
> "non-mfa" = [
> "admin",
> "super_admin",
> "user",
> ]
> }
Generated by:
{for k, v in {for k, v in local.user_pools : k => merge(local.merge_user_pool, v)} : k => v.roles}
I now want to flatten the output, so that I can ultimately use it in a for_each declaration, i.e. the final output would look something like:
{
"mfa" = "admin",
"mfa" = "super_admin",
"mfa" = "user",
"non-mfa" = "admin",
"non-mfa" = "super_admin",
"non-mfa" = "user"
}
Would appreciate any help given.
The desired output you give is not possible to represent in Terraform, as it is an object with repeated attribute names. Each attribute must have a unique name.
Since your goal here is a for_each
, I imagine the keys might have no particular requirement other than uniqueness. If that’s true, you might find creating composite keys suitable. Something like this:
merge([
for role, users in local.role_users: {
for user in users: "${role}-${user}" => user
}
]...)
The result:
{
"mfa-admin" = "admin"
"mfa-super_admin" = "super_admin"
"mfa-user" = "user"
"non-mfa-admin" = "admin"
"non-mfa-super_admin" = "super_admin"
"non-mfa-user" = "user"
}
Thanks for the prompt reply alisdair.
Subsequent to my posting I came to realise the output I was looking for was not possible. However, your reply has got me thinking that the solution I need is possibly in fact:
{
"mfa_admin" = {
"user_pool" = "mfa"
"role" = "admin"
}
"mfa-superadmin" = {
"user_pool" = "mfa"
"role" = "super_admin"
}
"mfa-user" = {
"user_pool" = "mfa"
"role" = "user"
}
.
.
.
}
This is because the output is to be used in the AWS resource aws_cognito_user_group which will need to know both the User Pool, which are labelled either “mfa” or “non-mfa”, and the IAM role, which are labelled “user”, “admin” or “super_admin”.
The merge solution you proposed is a step in the right direction, but I need to work out how to set values for “user_pool” and “role” as I’ll be able to reference each.value.user_pool and each.value.role for the appropriate value.
Thanks for your help.
I think what you’re looking for is something like this, then:
locals {
pool_roles = {
"mfa" = [
"admin",
"super_admin",
"user",
]
"non-mfa" = [
"admin",
"super_admin",
"user",
]
}
}
output "result" {
value = merge([
for pool, roles in local.pool_roles : {
for role in roles : "${pool}-${role}" => {
"user_pool" = pool,
"role" = role,
}
}
]...)
}
Gives:
result = {
"mfa-admin" = {
"role" = "admin"
"user_pool" = "mfa"
}
"mfa-super_admin" = {
"role" = "super_admin"
"user_pool" = "mfa"
}
"mfa-user" = {
"role" = "user"
"user_pool" = "mfa"
}
"non-mfa-admin" = {
"role" = "admin"
"user_pool" = "non-mfa"
}
"non-mfa-super_admin" = {
"role" = "super_admin"
"user_pool" = "non-mfa"
}
"non-mfa-user" = {
"role" = "user"
"user_pool" = "non-mfa"
}
}