Search code examples
terraform

When working with unknown values in for_each, it's better to define the map │ keys statically in your configuration and place apply-time results only


How to work around this error? I have tried multiple ways but still it gives me the same error.

variable "pets_count" {
  type = number
}

resource "random_pet" "my_pet" {
  count = var.pets_count
}

resource "null_resource" "ckeck" {
  for_each =  {for pet in try(random_pet.my_pet.*.id, []) : pet => {"name" = pet}}

  provisioner "local-exec" {
    command = "echo ${each.value.name}"
  }
}

this gives me the following error.

│ Error: Invalid for_each argument
│
│   on code.tf line 15, in resource "null_resource" "ckeck":
│   15:   for_each = local.pet_ids
│     ├────────────────
│     │ local.pet_ids will be known only after apply
│
│ The "for_each" map includes keys derived from resource attributes that
│ cannot be determined until apply, and so Terraform cannot determine the
│ full set of keys that will identify the instances of this resource.
│
│ When working with unknown values in for_each, it's better to define the map
│ keys statically in your configuration and place apply-time results only in
│ the map values.
│
│ Alternatively, you could use the -target planning option to first apply
│ only the resources that the for_each value depends on, and then apply a
│ second time to fully converge.

I have tried some more ways of looping over but it still ended up with the same error.


Solution

  • You can apply the code in two stages as indicated in the last line of the warning:

    you could use the -target planning option to first apply only the resources that the for_each value depends on, and then apply a second time to fully converge.

    Either by editing the code (commenting out the null_resource) or as they say with -target.

    The following sequence of actions with your code:

    terraform apply -target 'random_pet.my_pet'
    terraform apply
    

    worked.

    Explanation

    AFAIK, there's no way to force Terraform to perform two runs in one execution of the apply command. And basically two runs are needed to define your constellation of resources. Terraform (as most of the tools of the same principle) works in different phases - first it needs to establish what are the resources to be managed (created/destroyed/updated/imported/etc.) and then to perform these operations. Your code requires to execute: establish, then create, then establish, then create.