Search code examples
foreachterraformactive-directory

Terraform for_each loop over a list


Help to understand this Terraform loop behavior.

I'm creating Groups, Users and Group Memberships using Terraform Active Directory Provider, I'm testing creating 2 users and 2 groups and assign the users to the groups. Here is my code:

User:

resource "ad_user" "user1" {
  principal_name   = "user1"
  .
  .
}

output "user1_id" {
  value = ad_user.user1.id
}

Groups:

resource "ad_group" "group1" {
  name             = "group1"
  .
  .
}

variable "group1" {}

output "group1_id" {
  value = ad_group.group1.id
}

resource "ad_group_membership" "group1" {
    for_each = toset(var.group1)
    group_id = ad_group.group1.id
    group_members = [ each.value ]
}

Module:

module "groups" {
  source = ".//modules/groups"

  group1 =  [
    module.users.user1_id,
    module.users.user2_id
  ]
}

The behavior I see is when apply, the first time it does the creation and assignment to all users Ids in my var.group1, but if I apply again just to see if everything is complete, it shows me changes on the assignments to remove the assignations, and the next apply is to assign it back again and so on.

Probably is because I'm iterating over a list and have to change these values to a map instead, but not sure.

Thanks!


Solution

  • Based from the open Issue #94

    This is a bug in the provider.

    In the meantime I had to try the Workaround described, which solves my problem.

        # Create a variable to hold usernames
    variable "users" {
      type = list
      default = ["user_name_1","user_name_2"]
    }
    
    # Get Group id
    data "ad_group" "service_group" {
      group_id = "CN=TestGroup,OU=TestOU,DC=ad,DC=mydomain,DC=tld"
    }
    
    # loop through users and get there data
    data "ad_user" "user_data" {
      for_each = toset(var.users)
        user_id = each.value
    }
    # create a local that holds all of the id's
    locals {
      add_users = toset([for k, v in data.ad_user.user_data : v.id])
    }
    # use that list of ID's to add members to a group
    resource "ad_group_membership" "app_group_members" {
      group_id = data.ad_group.service_group_app.id
      group_members = local.add_users
    }
    output "user_id" {
      value = toset([for k, bd in data.ad_user.user_data : bd.id])
    }