Why `Invalid for_each argument error` happen

An invalid for_ach argument error occurred in the recursive call of the module(two depths).

my test code is below (dir: ./)

resource "random_id" "this" {
  byte_length = 8
}

module "module1_wrapper" {
  source = "./module_1"

  module_1_input = {
    module_2_input = {
      name = random_id.this.id
    }
  }
}

module_1(dir: ./module_1)

module "wrapper" {
  source = "../module_2"

  for_each = var.module_1_input

  module_2_input = try(each.value, null)
}

variable "module_1_input" {
  type    = any
  default = {}
}

module_2(dir: ./module_2)

resource "null_resource" "this" {
  for_each = var.module_2_input

}

variable "module_2_input" {
  type    = any
  default = {}
}

terraform error meesage

$ terraform plan
β•·
β”‚ Error: Invalid for_each argument
β”‚ 
β”‚   on module_2/main.tf line 2, in resource "null_resource" "this":
β”‚    2:   for_each = var.module_2_input
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ var.module_2_input 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.

As a result of conducting several tests, we found that errors occur depending on whether input var(module_2_input) of module_1 expression has a try function or not.

Terraform documentations say try function is …

try evaluates all of its argument expressions in turn and returns the result of the first one that does not produce any errors.

This is a special function that is able to catch errors produced when evaluating its arguments, which is particularly useful when working with complex data structures whose shape is not well-known at implementation time.

i guess below theory. Am i right?

in module_2_input expression, the first argument each.value of the try function is random_id.this.id. This argument is unknown until the terraform apply command is actually done. As a result, the try function does not seem to be able to perform an evaluation. So there seems to be an error in resource creation using the try() function’s result map.

Hi @pyo-counting,

for_each must be able to determine the keys during the plan phase so it can know whether it’s going to be creating, updating, or destroying each instance of the resource.

The β€œrandom” provider generates its random results during the apply phase, and so results from that provider are not suitable to use as instance keys in for_each.

1 Like