Terraform: Invalid dynamic for_each value. Cannot use a list of object value in for_each. An iterable collection is required

2.5k views Asked by At

Terraform version: "1.2.9"

Terraform fails with invalid value error when input variable with type list(object({})) and marked as sensitive = true is passed to dynamic block with for_each. The error is not seen when the input variable is marked as non-sensitive.

Input variable looks like below:

variable "sample_variable" {
  type = list(object({
    name = string
    description = optional(string)
    secure = optional(bool)
    type = string
    use_default = optional(bool)
    value = string
  }))
  sensitive   = true
  description = "A list of objects with sensitive values."
  default     = []
}

And is consumed in a resource dynamic block with a for_each as shown below:

resource "ibm_cloud_sample_resource" "my_resource" {
  name                     = var.name
  description              = var.description
  template_env_settings    = local.env_values
  tags                     = var.tags
  dynamic "template_inputs" {
    for_each = var.sample_variable
    content {
      name        = template_inputs.value.name
      description = template_inputs.value.description
      type        = template_inputs.value.type
      value       = template_inputs.value.value
      secure      = template_inputs.value.secure
      use_default = template_inputs.value.use_default
    }
  }
}

Error:

╷
│ Error: Invalid dynamic for_each value
│
│   on main.tf line 50, in resource "ibm_cloud_sample_resource" "my_resource":
│   50:     for_each = var.sample_variable
│     ├────────────────
│     │ var.sample_variable has a sensitive value
│
│ Cannot use a list of object value in for_each. An iterable collection is required.

Sample value from terraform.tfvars file:

sample_variable = [ 
  { name = "api_key"
    type = "string"
    value = "<sensitve_api_key_value>"
    secure = true 
  }, 
  { name = "other_variable"
    type = "string"
    value = "test_value_and_might_be_sensitive" 
  } 
]
2

There are 2 answers

2
Marcin On BEST ANSWER

You can't iterate over sensitive variables in dynamic blocks. The only way to make it work, is to use nonsensitive (can be dangerous!):

for_each = nonsensitive(var.sample_variable)

So its up to you to decide if you really need var.sample_variable to be sensitive or not. If it must be sensitive, you can't dynamically create your blocks and you have to re-architect your TF code to not require such an iteration.

0
Somnath Pathak On

As per the Terraform documentation for limitations of for_each loop, it seems we cannot iterate over sensitive input variables.

Sensitive values, such as sensitive input variables, sensitive outputs, or sensitive resource attributes, cannot be used as arguments to for_each. The value used in for_each is used to identify the resource instance and will always be disclosed in UI output, which is why sensitive values are not allowed. Attempts to use sensitive values as for_each arguments will result in an error.

This terraform GitHub issue describes the problem we are encountering with the aforementioned requirement.