As so many people before me (and most probably after me), I ran into the following dreaded problem:
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.
I did some digging and I must admit that no explanation really gives full insights into what the actual problem is. I thought I saw someone mentioning somewhere that for_each
can’t rely on variable parameters, which seems a bit silly as that is maybe one of the only reasons it’s useful to use (or at least a very important one).
I’ll illustrate with an example. In my code I’m creating a number of service accounts:
resource "google_service_account" "service_account_one" {
project = var.project_id
account_id = "sa-one"
}
resource "google_service_account" "service_account_two" {
project = var.project_id
account_id = "sa-two"
}
Now I want to give these service accounts a set of roles on particular objects. For example, granting them access to a storage bucket. Instead of copy/pasting the same resource 3 times, I thought I’d be smart and solve it with a locals list.
locals {
service_account_emails = [
google_service_account.service_account_one.email,
google_service_account.service_account_two.email,
]
}
And then give them the desired IAM role:
resource "google_storage_bucket_iam_member" "configuration_access" {
for_each = toset(local.service_account_emails)
bucket = google_storage_bucket.configuration_bucket.name
member = "serviceAccount:${each.value}"
role = "roles/storage.admin"
}
But, as you already guessed:
â•·
│ Error: Invalid for_each argument
│
│ on ../../../main.tf, in resource "google_storage_bucket_iam_member" "configuration_access":
│ 345: for_each = toset(local.service_account_emails)
│ ├────────────────
│ │ local.service_account_emails is tuple with 2 elements
│
│ 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.
╵
So, can someone shed some light on what is happening in the background here? As you can see, it’s a fixed list with 2 elements, so I have no idea why Terraform can’t predict how many elements are going to be created.
This isn’t the first time I’m running into this problem. I have other examples where it’s problematic as well, especially with flattened lists and passing in variables into a module.
Is there work underway to solve this problem or at least give a better error message and guidance on how to solve this?