terraformterraform-provider-ibmterraform-loop

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


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" 
  } 
]

Solution

  • 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.