AD Group Management Example: The "for_each" value depends on resource attributes that cannot be determined until apply

The Azure AD user management example on Hashicorp Learn has this bug which causes the example to fail when a new user is added to users.csv:

(Manage Azure Active Directory (Azure AD) Users and Groups | Terraform - HashiCorp Learn)

(base) welcome@my-MacBook-Pro azure-ad-management % terraform plan -out terraform.plan
random_pet.suffix: Refreshing state... [id=kind-krill]
azuread_group.contracting: Refreshing state... [id=8e4bf5a6-9ffa-4125-8144-91d6b73fdb3d]
azuread_group.managers: Refreshing state... [id=fec6ebc0-0812-4b77-97f1-26dc701580c3]
azuread_group.engineers: Refreshing state... [id=3f3a9135-08ae-4565-b8b1-5a4273c0c46a]
azuread_user.users["Joe"]: Refreshing state... [id=41ca263c-7733-42e7-a3a2-395e147d4227]
azuread_user.users["Ivan"]: Refreshing state... [id=732d933f-3a37-41ed-915d-3c0bfcdc2a2d]
azuread_user.users["Tom"]: Refreshing state... [id=66015e99-15c6-4384-961a-37e911a43b08]
azuread_group_member.managers["tjones-kind-krill"]: Refreshing state... [id=fec6ebc0-0812-4b77-97f1-26dc701580c3/member/66015e99-15c6-4384-961a-37e911a43b08]
β•·
β”‚ Error: Invalid for_each argument
β”‚ 
β”‚   on groups.tf line 10, in resource "azuread_group_member" "contracting":
β”‚   10:   for_each         = { for u in azuread_user.users : u.mail_nickname => u if u.department == "Contracting" }
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ azuread_user.users is object with 4 attributes
β”‚ 
β”‚ The "for_each" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created. To work around this, use the -target argument to first apply only the resources that the for_each depends on.
β•΅
β•·
β”‚ Error: Invalid for_each argument
β”‚ 
β”‚   on groups.tf line 32, in resource "azuread_group_member" "engineers":
β”‚   32:   for_each         = { for u in azuread_user.users : u.mail_nickname => u if u.job_title == "Engineer" }
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ azuread_user.users is object with 4 attributes
β”‚ 
β”‚ The "for_each" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created. To work around this, use the -target argument to first apply only the resources that the for_each depends on.
β•΅

A terrible workaround I can use is to mask out the β€œresource β€œazuread_group_member” …” blocs , however that results in deletion of these resources. Then, once I apply and create the new user, I can unmask the blocs, rerun and everything is fine.
However, this is far from the ideal way to manage AD users …

What is the solution for this?

How to re-produce:

  1. Follow the example in the Hashicorp Learn article: Manage Azure Active Directory (Azure AD) Users and Groups | Terraform - HashiCorp Learn

Hi @archmangler,

What this error is meant to convey (newer Terraform versions will have even better text here to help explain the situation) is that the for_each keys are not fully known during the plan, so there is no way to plan the azuread_group_member instances. This is because mail_nickname is a computed attribute in the example config, and will not be known until the azuread_user resource is first applied. You must use a known attribute such as user_principal_name as the for_each key in order to properly plan the resources.

1 Like