10

Does anyone know if it's possible with possibly code snipits representing whether I can create a map variable within a map variable in terraform variables?

variable "var" {
  type = map
  default = {
    firstchoice = {
      firstAChoice ="foo"
      firstBChoice = "bar"
    }
    secondchoice = {
      secondAChoice = "foobar"
      secondBChoice = "barfoo"
    }
  }
}

If anyone has any insight to whether this is possible or any documentation that elaborates that would be great.

Amit Yadav
  • 4,422
  • 5
  • 34
  • 79
IsaacD
  • 171
  • 1
  • 1
  • 7

2 Answers2

24

Yes, it's possible to have map variable as value of map variable key. Your variable just needed right indentation. Also I am putting ways to access that variable.

variable "var" {
  default = {
    firstchoice = {
      firstAChoice = "foo"
      firstBChoice = "bar"
    }

    secondchoice = {
      secondAChoice = "foobar"
      secondBChoice = "barfoo"
    }
  }
}

To access entire map value of a map key firstchoice, you can try following

value = "${var.var["firstchoice"]}"

output:
{
  firstAChoice = foo
  firstBChoice = bar
}

To access specific key of that map key (example firstAChoice), you can try

value = "${lookup(var.var["firstchoice"],"firstAChoice")}"

output: foo
Avichal Badaya
  • 3,423
  • 1
  • 21
  • 23
11

Would this syntax be possible? ${var.var[firstchoice[firstAchoice]]}

With Terraform 0.12+ nested blocks are supported seamlessly. Extending @Avichal Badaya's answer to explain it using an example:

# Nested Variable

variable "test" {
  default = {
    firstchoice = {
      firstAChoice = "foo"
      firstBChoice = "bar"
    }

    secondchoice = {
      secondAChoice = "foobar"
      secondBChoice = "barfoo"
    }

    thirdchoice = {
      thirdAChoice = {
          thirdBChoice = {
              thirdKey = "thirdValue"
        }
      }
    }
  }
}


# Outputs

output "firstchoice" {
  value = var.test["firstchoice"]
}

output "FirstAChoice" {
  value = var.test["firstchoice"]["firstAChoice"]
}

output "thirdKey" {
  value = var.test["thirdchoice"]["thirdAChoice"]["thirdBChoice"]["thirdKey"]
}

Applying the above, you can verify that Terraform map nesting is now quite powerful and this makes a lot of things easier.

# Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

# Outputs:

firstchoice = {
  "firstAChoice" = "foo"
  "firstBChoice" = "bar"
}

thirdKey = thirdValue 

For more complex structures and Rich Value Types, see HashiCorp Terraform 0.12 Preview: Rich Value Types

Amit Yadav
  • 4,422
  • 5
  • 34
  • 79
  • 2
    I like this updated answer. It makes the code a lot more readable. Would it be possible to traverse the map using the dot notation? For example: `var.test.firstchoice.firstAchoice`? – Alex Mar 23 '21 at 03:18
  • 1
    Yes. You can give it a try using `terraform console` (https://www.terraform.io/cli/commands/console) – donhector Apr 26 '22 at 22:53