# Run for loop over nested local structure

**URL:** <https://discuss.hashicorp.com/t/run-for-loop-over-nested-local-structure/44484>\
**Category:** Terraform\
**Created:** [September 19, 2022, 12:54pm UTC](https://discuss.hashicorp.com/t/run-for-loop-over-nested-local-structure/44484 "2022-09-19T12:54:21Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![revaner](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/revaner/32/25815_2.png) [@revaner](https://discuss.hashicorp.com/u/revaner)\
**Post date:** [September 19, 2022, 12:54pm UTC](https://discuss.hashicorp.com/t/run-for-loop-over-nested-local-structure/44484/1 "2022-09-19T12:54:21Z")

</div>

Hi,  
I’m trying to run `for` loop over the local structure like:

```auto
locals {

  aws_iam_roles = {

    role1 = {
      role_name = "Role1"
      role_policies = ["Policy1", "Policy2"]
    }

    role2 = {
      role_name = "Role2"
      role_policies = ["Policy3"]
    }
  }
}

```

to achieve structure like:

```auto
{
Role1 = Policy1
Role1 = Policy2
Role2 = Policy3
}

```

I will appreciate any suggestions. Best Regards!

Update:  
What I’m done is:

```auto
locals {
  policy_role_pairs = [
    for r, p in local.aws_iam_roles : {
      for n in p.role_policies : 
        n => p.role_name
    }
  ]
}

```

But it produces:

```auto
policy_role_pairs = [
  {
    "Policy1" = "Role1"
    "Policy2" = "Role2"
  },
  {
    "Policy3" = "Role3"
  },
]

```

Which is nice but I cannot run `for_each` on that structure which is my final goal.

---

<div class="post-metadata">

**Author:** ![jbardin](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/jbardin/32/3325_2.png) [@jbardin](https://discuss.hashicorp.com/u/jbardin)\
**Post date:** [September 19, 2022, 1:41pm UTC](https://discuss.hashicorp.com/t/run-for-loop-over-nested-local-structure/44484/2 "2022-09-19T13:41:46Z")

</div>

Hi @revaner,

I think part of the problem here is that the structure you are looking for isn’t valid. The object or map shown here contains a duplicate key:

```auto
{
Role1 = Policy1
Role1 = Policy2
Role2 = Policy3
}

```

Would something more like this suit your needs?

```auto
> flatten([ for p in local.aws_iam_roles :
  [for n in p.role_policies : { (p.role_name) = n }]
])

[
  {
    "Role1" = "Policy1"
  },
  {
    "Role1" = "Policy2"
  },
  {
    "Role2" = "Policy3"
  },
]

```

---

<div class="post-metadata">

**Author:** ![revaner](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/revaner/32/25815_2.png) [@revaner](https://discuss.hashicorp.com/u/revaner)\
**Post date:** [September 19, 2022, 2:03pm UTC](https://discuss.hashicorp.com/t/run-for-loop-over-nested-local-structure/44484/3 "2022-09-19T14:03:22Z")

</div>

Hi @jbardin  
Many thanks, it’s producing pairs as expected but I still wonder how to make it work with `for_each` loop on that output?

---

<div class="post-metadata">

**Author:** ![jbardin](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/jbardin/32/3325_2.png) [@jbardin](https://discuss.hashicorp.com/u/jbardin)\
**Post date:** [September 19, 2022, 2:17pm UTC](https://discuss.hashicorp.com/t/run-for-loop-over-nested-local-structure/44484/4 "2022-09-19T14:17:22Z")

</div>

How to make _what_ work exactly? If you are trying to use the key-value pairs in a resource `for_each` expression, you would have the same problem that made the first example invalid, there are duplicate keys in the data. You will always need unique keys for individual instances, just like you need unique keys for each map value. Can you show the actual final data you would need for the resource in question?

---

<div class="post-metadata">

**Author:** ![revaner](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/revaner/32/25815_2.png) [@revaner](https://discuss.hashicorp.com/u/revaner)\
**Post date:** [September 19, 2022, 2:24pm UTC](https://discuss.hashicorp.com/t/run-for-loop-over-nested-local-structure/44484/5 "2022-09-19T14:24:21Z")

</div>

Ouh, I wasn’t aware that for `for_each` I need unique keys but I’ve tested and indeed. Maybe I’ve started story from the middle. Let me describe whole scenario.

I’m working on AWS IAM module which will do few things:

1. Create IAM Roles
2. Get IAM Policy ARN
3. Attach IAM Policies to IAM Roles

My current `local` values are:

```auto
locals {

  aws_iam_roles = {

    role1 = {
      role_name = "Role1"
      role_policies = ["Policy1", "Policy2"]
    }

    role2 = {
      role_name = "Role2"
      role_policies = ["Policy3"]
    }
  }
}

```

Based on that local input I’m creating IAM Roles and using data block to get all Policies ARNs.

```auto
locals {
  role_policies_merged = toset(flatten([for r, p in local.aws_iam_roles : p.role_policies]))
  policy_role_pairs = flatten([for r, p in local.aws_iam_roles : [for n in p.role_policies : { (p.role_name) = n }]])
}

```

```auto
data "aws_iam_policy" "role_policy" {
  for_each = local.role_policies_merged
  name = each.value
}

```

Here I need the pairs: Role - Policy to run for\_each over them.  
My current issue is here:

```auto
resource "aws_iam_role_policy_attachment" "role_policy" {
  for_each = { for r, p in local.policy_role_pairs : r => p }
  role = each.key
  policy_arn = data.aws_iam_policy.role_policy[each.key].arn
}

```

I hope now it’s more clear.

---

<div class="post-metadata">

**Author:** ![jbardin](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/jbardin/32/3325_2.png) [@jbardin](https://discuss.hashicorp.com/u/jbardin)\
**Post date:** [September 19, 2022, 2:39pm UTC](https://discuss.hashicorp.com/t/run-for-loop-over-nested-local-structure/44484/6 "2022-09-19T14:39:21Z")

</div>

You must have a unique key for each instance. One option is to create the key from the combination of the key-value pair. Maybe something like this (just typing this out, so assignments and values may not be quite correct)

```auto
policy_role_pairs = { for pair in concat([ for role_name, role in local.aws_iam_roles : 
    setproduct([role_name], role.role_policies)]...) : 
  format("%s_%s", pair...) => pair
}
...
resource "aws_iam_role_policy_attachment" "role_policy" {
  for_each = for each in local.policy_role_pairs 
  role = each[0]
  policy_arn = data.aws_iam_policy.role_policy[each[1]].arn
}

```

---

<div class="post-metadata">

**Author:** ![revaner](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/revaner/32/25815_2.png) [@revaner](https://discuss.hashicorp.com/u/revaner)\
**Post date:** [September 19, 2022, 6:53pm UTC](https://discuss.hashicorp.com/t/run-for-loop-over-nested-local-structure/44484/7 "2022-09-19T18:53:58Z")

</div>

Hello @jbardin ,  
Thank you for your quick and amazing support.  
It works for me now with grouping Role - Policy pairs with unique index following your suggestion and attachment block like:

```auto
resource "aws_iam_role_policy_attachment" "role_policy" {
  for_each = local.policy_role_pairs
  role = each.value[0]
  policy_arn = data.aws_iam_policy.role_policy[each.value[1]].arn
}

```

Best Regards!
