bruvio
bruvio

Reputation: 1093

How to create a dynamic block from a list of objects?

I have a terraform variable:

variable "volumes" {
  default = [
    {
      "name" : "mnt",
      "value" : "/mnt/cvdupdate/"
    },
    {
      "name" : "efs",
      "value" : "/var"
    },
  ]
}

and I am trying to create a dynamic block

  dynamic "volume" {
    for_each = var.volumes == "" ? [] : [true]
    content {
      name = volume["name"]
    }
  }

but I get an error when I run plan

name = volume["name"]
│
│ The given key does not identify an element in this collection value.

The desired output would be:

  volume {
    name = "mnt"
  }

  volume {
    name = "efs"
  }

What is wrong with my code?

Upvotes: 2

Views: 1691

Answers (3)

Youcef LAIDANI
Youcef LAIDANI

Reputation: 59978

You can simply use for_each = var.volumes[*]:

dynamic "volume" {
  for_each = var.volumes[*]
  content {
    name = volume.value["name"]
  }
}

or:

dynamic "volume" {
  for_each = var.volumes[*]
  content {
    name = volume.value.name # <------
  }
}

Upvotes: 1

devops_gagan
devops_gagan

Reputation: 89

As you are creating an if-else like condition to pass value to for loop, the condition needs a value to set. https://developer.hashicorp.com/terraform/language/meta-arguments/for_each

  • Need to replace [true] with var.volumes to pass the value. for_each = var.volumes == "" ? [] : var.volumes
  • And, then set the value in the content block with .value to finally set the values to use.
    content {
      name = volume.value["name"]

The final working code is below as @marcin posted.

  dynamic "volume" {
    for_each = var.volumes == "" ? [] : var.volumes
    content {
      name = volume.value["name"]
    }
  }

Upvotes: 1

Marcin
Marcin

Reputation: 238209

Since you are using for_each, you should use value. Also you condition is incorrect. It all should be:

  dynamic "volume" {
    for_each = var.volumes == "" ? [] : var.volumes
    content {
      name = volume.value["name"]
    }
  }

Upvotes: 4

Related Questions