First, a quick digression into code layout - I think your code would be more readable if you did not use locals
so much. If you have an expression that is only used in one for_each
, just write it inline where needed. This means the reader doesn’t need to track down the definition in another file, to understand how a given block is being parameterized.
You can even move the variable
block associated with each function to be with its other blocks as well - there’s nothing special about the filename variables.tf
.
But that’s just my opinion on code style.
The actual problem with this code:
is that team-membership
holds the list of members. Terraform complains that asking for .username
of a list doesn’t make sense.
What you actually need is something more like this:
resource "github_team_membership" "members" {
for_each = {
for item in flatten([
for team_name, team_members in var.github_team_members : [
for member in team_members : {
team_name = team_name
username = member.username
role = member.role
}
]
])
: "${item.team_name} ${item.username}" => item
}
team_id = github_team.all[each.value.team_name].id
username = each.value.username
role = each.value.role
}
Note the complex for_each
expression that:
- loops over teams (middle
for
)
- loops over members within each team (innermost
for
)
- captures all the relevant info from multiple levels of looping into one object (innermost pair of curly braces)
- turns the flattened list of objects back into a map, assigning a suitably unique string key to each membership (outermost
for
)
Also note that you no longer need to explicitly write out a depends_on
since Terraform can already observe the dependency from the direct reference to github_team.all[each.value.team_name].id
.
That should take care of the team memberships.
Separately I believe you have an issue with the organization memberships:
resource "github_membership" "organization_memberships" {
for_each = {
for mem in var.github_organization_members : "${mem.username}-${mem.role}" => mem
}
username = each.value.username
role = each.value.role
}
(In the above, I’ve updated the code style to match what I said at the start of this reply, so we can look at the for_each
expression in the context of the whole resource
block.)
The problem is that you’re using username and also role as part of the unique key - I’m pretty sure that’s not how GitHub works - I believe you can’t add the same user as both a member and an admin - instead, admin includes member rights.