Reputation: 25
I'm trying to write a Terraform module whose purpose is to add members (users and service principals) to Azure AD groups. Here's my code:
# This is our input which contains the display names of users, SPNs and groups
memberships_service_principals = {
"spn1" = "group1"
"spn2" = "group2"
}
memberships_users = {
"user1" = "group1"
"user1" = "group2"
"user2" = "group2"
}
# Here we get each SPN's group object ID
data "azuread_group" "groups_service_principals" {
for_each = var.memberships_service_principals
display_name = each.value
}
# Here we get each SPN's object ID
data "azuread_service_principal" "service_principals" {
for_each = var.memberships_service_principals
display_name = each.key
}
# Here we get each user's group object ID
data "azuread_group" "groups_users" {
for_each = var.memberships_users
display_name = each.value
}
# Here we get each user's object ID
data "azuread_user" "users" {
for_each = var.memberships_users
user_principal_name = each.key
}
# Here we construct and merge two maps of groups => object IDs
locals {
service_principal_object_ids = { for k, v in var.memberships_service_principals : data.azuread_service_principal.service_principals["${k}"].object_id => data.azuread_group.groups_service_principals["${k}"].object_id }
user_object_ids = { for k, v in var.memberships_users : data.azuread_user.users["${k}"].object_id => data.azuread_group.groups_users["${k}"].object_id }
member_object_ids = merge(local.service_principal_object_ids, local.user_object_ids)
}
# Here we configure the memberships by passing the group and SPN/user object IDs
resource "azuread_group_member" "group_members" {
for_each = var.member_object_ids
group_object_id = each.value
member_object_id = each.key
}
Unfortunately, the above code doesn't work because a map in Terraform can have only unique keys. This rule gets violated in these cases:
I tried to define my input as follows but I still have no idea how to come up with a map of unique keys which to pass to create the memberships via 'resource "azuread_group_member"':
locals {
test_input1 = [
{principal = "user1", groups = ["group1", "group2"]},
{principal = "user2", groups = ["group2"]}
]
test_input2 = [
{ "user1" = ["group1", "group2"] },
{ "user2" = ["group2"] }
]
}
Any help and/or ideas will be greatly appreciated!
Upvotes: 0
Views: 307
Reputation: 238081
I don't fully understand your setup, but you could create a map from your variables with unique keys as follows:
variable "memberships_users" {
default = {
"user1" = "group1"
"user1" = "group2"
"user2" = "group2"
}
}
locals {
service_users = merge([
for k1,v1 in var.memberships_service_principals:
{
for k2,v2 in var.memberships_users:
"${k1}-${k2}" => {
memberships_service_principal = k1
memberships_service_principal_group = v1
memberships_user = k2
memberships_user_group = v2
}
}
]...)
}
which gives:
service_users = {
"spn1-user1" = {
"memberships_service_principal" = "spn1"
"memberships_service_principal_group" = "group1"
"memberships_user" = "user1"
"memberships_user_group" = "group2"
}
"spn1-user2" = {
"memberships_service_principal" = "spn1"
"memberships_service_principal_group" = "group1"
"memberships_user" = "user2"
"memberships_user_group" = "group2"
}
"spn2-user1" = {
"memberships_service_principal" = "spn2"
"memberships_service_principal_group" = "group2"
"memberships_user" = "user1"
"memberships_user_group" = "group2"
}
"spn2-user2" = {
"memberships_service_principal" = "spn2"
"memberships_service_principal_group" = "group2"
"memberships_user" = "user2"
"memberships_user_group" = "group2"
}
}
Then you could use that:
# SAMPLE CODE. Its not clear what you wish to accomplish,
# thus some changes probably will be required!
resource "azuread_group_member" "group_members" {
for_each = local.service_users
group_object_id = data.azuread_group.groups_service_principals[each.value.memberships_service_principal].object_id
member_object_id =data.azuread_group.groups_users[each.value.memberships_user].object_id
}
Upvotes: 2