Skip to main content

Terraform Map

All the code should be put in a file called main.tf in the root of the project folder. Just cut-and-paste.

Showing results

The code in this article does nothing with providers, only variables and outputs in Terraform. So, deployment is done by a Terraform Apply

$ terraform apply --auto-approve

Map

The Map we are working with

variable "MAP_1" {
type = map(string)
default = {
keyA = "ValueA"
keyB = "ValueB"
keyC = "ValueC"
}
}

Get the 'keyC' value from the Map

(Same main.tf)

output "OUT_MAP_1" {
value = var.MAP_1["keyC"]
}

Output

OUT_MAP_1 = "ValueC"

Get all values in the Map

output "OUT_MAP_1_ALL_VALUES" {
value = var.MAP_1
}

Output

OUT_MAP_1_ALL_VALUES = tomap({
"keyA" = "ValueA"
"keyB" = "ValueB"
"keyC" = "ValueC"
})

Per Element

Let's do something on a per element basis. Since we don't have a resource, we need a submodule to play around with that.

Submodules in Terraform are very simple:

  • Create a subdirectory with any name
  • Specify the submodule in main.tf (in root dir), give it any name.
  • And tell that main.tf where to find the source of the module

And we will use the 'for_each' Meta Argument

for_each Meta Argument

Specify the module in the main.tf file

module "MAP_PER_ELEMENT" {
source = "./module_map_element"
for_each = var.MAP_1
mapElementKey = each.key
mapElementValue = each.value
}

This means the following:

  • The source of the module is in a subdir called module_map_element.
  • for_each means that we will call the module for each element in the var.MAP_1.
  • We pass a variable called 'mapElementKey' with the value of the key:
    "keyA", "keyB", "keyC".
  • And a value of that key in the map: "ValueA", ... (maybe I should use more realistic values here 😉)

What happens is that this module is called automatically for each (!!) occurrence of a key in the map.

Inside the module

The module also has a main.tf file with the following contents
(located in subdir ./module_map_element/main.tf)

variable "mapElementKey" {
type = string
}

variable "mapElementValue" {
type = string
}

output "MODULE_MAP_ELEMENT_OUTPUT" {
value = "${var.mapElementKey} = ${var.mapElementValue}"
}

Since you are passing 2 variables into the module, they have to be 'caught' by variables inside the module. Therefore, the two variable definitions.

And then you can use them in 'resources' inside the module, or 'output' statements like we do here. The only thing the output does is make a string available named "MODULE_MAP_ELEMENT_OUTPUT" to the outside world.

Back in the root module

The main.tf file in the root is often called the root module.

There the module is called (3 times) and we can access the output from the module.

In root module, main.tf:

output "MODULE_MAP_ELEMENT_OUTPUT" {
value = module.MAP_PER_ELEMENT
}

Output

MODULE_MAP_ELEMENT_OUTPUT = {
"keyA" = {
"MODULE_MAP_ELEMENT_OUTPUT" = "keyA = ValueA"
}
"keyB" = {
"MODULE_MAP_ELEMENT_OUTPUT" = "keyB = ValueB"
}
"keyC" = {
"MODULE_MAP_ELEMENT_OUTPUT" = "keyC = ValueC"
}
}