'Unable to create a map variable with Terraform

I'm trying to create a variable in my variables file which I thought I could do with a map, but it's not working.

In my variables.tf file, I have:

boot_disk = list(string)

Then in my vars file, I provide these values:

boot_disk               = {
                                image = "string"
                                size  = 1000
                                type  = "string"
                              }

Since "size" is an integer, I think that's causing my problem. Could someone help with this problem? My Jenkins job keeps failing.

I also have this defined in my vars file:

attached_disks = {
      name  = "string"
      size = 100
      image = "string"
    },
    {
      name = "string"
      size = 200
      image = "string"
    },
    {
      name = "string"        
      size = 100
      image = "disk"         
    }

But I don't know how to declare this in my variables.tf file Right now it looks like:

attached_disks          = map(object({
                            name = string
                            size = number
                            image = string}))


Solution 1:[1]

For boot_disk, value of list type variable has to be given in square bracket [] Go through this: https://www.terraform.io/language/values/variables

For attached_disks try below:

attached_disks          = list(object({
                            name = string
                            size = number
                            image = string}))

Also, modify your tfvars file to below:

attached_disks = [{
      name  = "string"
      size = 100
      image = "string"
    },
    {
      name = "string"
      size = 200
      image = "string"
    },
    {
      name = "string"        
      size = 100
      image = "disk"         
    }
]

Solution 2:[2]

There are a couple of issues with the code you have provided. For example, you say you want a map for your variable but you define it as a list of strings, i.e., list(string). This means that terraform will expect the values to be something like boot_disk = ["string1", "string2", "string3"]. With the value assignment you have:

boot_disk = {
  image = "string"
  size  = 1000
  type  = "string"
}

you are indeed creating a map. This will of course not work as expected as you are trying to assign a map to a variable of type list(string).

Lists have indexes and values while maps have keys and values. This means you can access a list element by specifying an index, e.g., if the boot_disk was really a list then you could get the value which is sitting in 2nd place like this: var.boot_disk[1]. Note that the indexing starts with 0, so for a list of three elements the indexes will be 0, 1, and 2. With maps, you would be able to get the value of an element by accessing the key of the element. If the boot_disk was a map, then you could access the size with: var.boot_disk["size"]. Alternatively, you could use a different way to access the same value with var.boot_disk.size. More information about different types of variables can be found in [1]. An example of how to work with variables you can find in [2].

To define boot_disk as a map you need to do the following:

variable "boot_disk" {
  type = map(object({
    image = string
    size  = number
    type  = string
  }))
  description = "Boot disk features."

  default = {
   image = "imagename"
   size  = 1000
   type  = "disktype"
  }
}

The attached_disks variable looks fine if that is what you intended to do with it.


[1] https://www.terraform.io/language/expressions/types

[2] https://learn.hashicorp.com/tutorials/terraform/aws-variables

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2