I am writing a module that needs to create "aws_iam_group_policy_attachment" resources. This resource requires a group name (string) and a policy name (string). I tried using different data structures, but the ones that make most sense look like this:
List of maps:
iam_groups = [
{ name = "testgroup1", policies = [ "Arn1", "Arn2" ] },
{ name = "testgroup2", policies = [ "Arn1", "Arn3", "Arn4" ] }
]
Map of maps:
iam_groups = {
"testgroup1" = { name = "testgroup1", policies = ["Arn1", "Arn2" ] }
"testgroup2" = { name = "testgroup2", policies = ["Arn1", "Arn3", "Arn4" ] }
}
Because that resource doesn't support supplying a list of policies, my thinking was that I need to create a structure that supports every combination of Group:Policy per group, so I defined a helper local variable with nested for loops:
groups = flatten([ for group in var.iam_groups : [ for policy in group.policies : { (group.name) = policy } ] ])
This gives me the correct combination of values:
GROUPS = [
{
testgroup1 = "Arn1"
},
{
testgroup1 = "Arn2"
},
{
testgroup2 = "Arn1"
},
{
testgroup2 = "Arn3"
},
{
testgroup2 = "Arn4"
},
]
Now, my question is how to use this in the "aws_iam_group_policy_attachment" resource?
Also, is there some other, better way to structure my data to achieve this?
I tried using:
resource "aws_iam_group_policy_attachment" "this" {
for_each = local.groups
group = each.key
policy_arn = each.value
}
But this gives an error that "for_each" requires a map or list of strings where I have a "tuple" with multiple elements.
What I want to avoid is maintaining a variable that has to manually and statically map all groups to each individual policy with a lot of repetition.
CodePudding user response:
It would be better to use map for the for each, not list, as list depends on the order of the items:
locals {
groups = merge([ for group in var.iam_groups : {
for policy in group.policies :
"${group.name}-${policy}" => {
policy = policy
group_name = group.name
}
} ]...) # please do NOT remove the dots
}
then
resource "aws_iam_group_policy_attachment" "this" {
for_each = local.groups
group = each.value.group_name
policy_arn = each.value.policy
}