My problem statement is simple but I am not able to find a solution anywhere on the internet.
I have users list as locals
:
// users
locals {
allUsers = {
dev_user_1 = {
Name = "user1"
Email = "user1@abc.com"
GitHub = "user1" # github username
Team = "Dev"
}
devops_user_2 = {
Name = "user2"
Email = "user2@abc.com"
GitHub = "user2" # github username
Team = "DevOps"
}
product_user_3 = {
Name = "user3"
Email = "user3@abc.com"
Team = "Product"
}
}
}
These are the local
tags that are being used for purposes of creating access to internal tools such as Github, Monitoring tools, etc.
Now, for the 2 users who belong to the Dev
and DevOps
team, they need access to Github ORG, while, the product user only needs access to some dashboards but not to Github, hence, the tag is missing.
How can I loop over the terraform resource github_membership
to skip this product user (or simply anyone who does not have tag key
GitHub?)
I am trying the following code, but no luck
// Send GitHub invite
resource "github_membership" "xyzTeam" {
for_each = local.allUsers
username = each.value.GitHub
role = "member"
}
Errors:
╷
│ Error: Unsupported attribute
│
│ on users.tf line 12, in resource "github_membership" "xyzTeam":
│ 12: username = each.value.GitHub
│ ├────────────────
│ │ each.value is object with 3 attributes
│
│ This object does not have an attribute named "GitHub".
key
for everyone but it's value
as null
.
Error:╷
│ Error: "username": required field is not set
│
│ with github_membership.xyzTeam["user3"],
│ on users.tf line 10, in resource "github_membership" "xyzTeam":
│ 10: resource "github_membership" "devops" {
│
╵
Error: PATCH https://api.github.com/user/memberships/orgs/XYZ: 422 You can only update an organization membership's state to 'active'. []
for k, v in local.allUsers : k => v if v != ""
Same error because it tries to create the user with empty value still, and fails ultimately.I cannot think of anything else. If someone can help to create separate locals
from these existing locals
, which creates the list of locals
that grep the GitHub
values, that hack would be super helpful.
You had the right idea with your third attempt, but the conditional logic in the for expression is slightly off. You need to use the can
function instead:
{ for user, attributes in local.allUsers : user => attributes if can(attributes.GitHub) }
If the nested map contains a Github
key, then can(attributes.Github)
returns true
, and the map constructor will contain the key-value pair. With this algorithm, you can construct a new map from the old map with the entries removed that do not contain a Github
key in the nested map value.