Produce maps from list of strings of a map

Hi @sleterrier!

It looks like your base need here is to find all of the combinations of policy and user given in your variable value. We can start by solving just that problem, not worrying too much about how the result is shaped:

locals {
  user_policy_pairs = flatten([
    for policy, users in var.iam-policy-users-map : [
      for user in users: {
        policy = policy
        user   = user
      }
    ]
  ])
}

The local.user_policy_pairs value would then be the following, with your example input:

[
  {
    policy = "policy1"
    user   = "user1"
  },
  {
    policy = "policy2"
    user   = "user1"
  },
  {
    policy = "policy2"
    user   = "user2"
  },
]

If having these grouped together into unique pairs is all you need and the exact data structure isn’t important then it might be better to use these objects to represent the pairs, since it’ll be clearer elsewhere in the configuration where it’s used what purpose each of the attributes has, rather than having to remember that element zero is the policy and element one is the user:

output "association-map" {
  value = {
    for obj in local.user_policy_pairs : "${obj.policy}_${obj.user}" => obj
  }
}

Your later each references would then be like each.value.user rather than each.value[1].

But if you do need that map-of-lists structure then you can produce it by transforming the previous result:

output "association-map" {
  value = {
    for obj in local.user_policy_pairs : "${obj.policy}_${obj.user}" => [obj.policy, obj.user]
  }
}

Please note that usual Terraform style is to use names that consist only of lowercase letters, numbers, and underscores. Terraform supports uppercase letters and dashes in identifiers only to make it more convenient to write names that will be sent to remote systems that may have different conventions. Your input variable would ideally be named iam_policy_users_map instead, and likewise your output value be association_map.

1 Like