Introduction
When managing infrastructure as code with Terraform, you often need to organize data in a way that supports dynamic configurations. This can include converting two related lists — one of keys and another of values — into a map. Such a transformation can streamline variable management, data lookup, and resource configuration. In this tutorial, we’ll cover how to achieve this in Terraform, progressing from basic to advanced examples.
Let’s start by understanding the basic structure and syntax in Terraform for list and map creation before diving into how to effectively combine both.
Basics of Lists and Maps in Terraform
Lists are ordered collections of values that can be of the same type, accessed by their index. Maps, on the other hand, are collections of key-value pairs that provide a more descriptive way to organize and access data. Here’s how simple lists and maps look in Terraform:
variable "example_list" {
type = list(string)
default = ["item1", "item2", "item3"]
}
variable "example_map" {
type = map(string)
default = {"key1" : "value1", "key2": "value2", "key3": "value3"}
}
Creating a Map from Two Lists
Now, we’re ready to proceed to our main topic: creating a map from two lists. The most straightforward approach in Terraform 0.12 and later versions is using the zipmap
function.
locals {
keys = ["key1", "key2", "key3"]
values = ["value1", "value2", "value3"]
result_map = zipmap(local.keys, local.values)
}
output "result_map" {
value = local.result_map
}
This code produces the following output when applied:
{
"key1" = "value1"
"key2" = "value2"
"key3" = "value3"
}
Handling Lists of Different Lengths
What happens if our lists of keys and values are of different lengths? By default, zipmap
will error out. To handle this gracefully, we can use a combination of the count
parameter and conditional expressions to ensure our lists are the same length or to fill in missing values.
Here’s an advanced example, adjusting for potentially unmatched list lengths:
locals {
keys = ["key1", "key2", "key3", "key4"]
values = ["value1", "value2", "value3"]
padded_values = length(local.keys) > length(local.values) ? concat(local.values, repeat("default", length(local.keys) - length(local.values))) : local.values
result_map = zipmap(local.keys, local.padded_values)
}
output "result_map" {
value = local.result_map
}
This example demonstrates how to ensure every key in our map gets a value, even if our original value list is too short. The output would adjust as needed, padding with “default” for any keys beyond the original list’s length.
Dynamic Map Creation with For Loops
In scenarios where zipmap
might not offer the flexibility needed, Terraform’s for
loop syntax can be used to dynamically create maps from two lists, allowing for more complex transformations or conditions as needed.
Here’s how to accomplish this with a for
loop:
locals {
keys = ["alpha", "beta", "gamma"]
values = [1, 2, 3]
dynamic_map = { for i, k in local.keys : k => local.values[i] if local.values[i] > 1 }
}
output "dynamic_map" {
value = local.dynamic_map
}
This creates a map just like before but filters the entries to only include those where the value is greater than 1. The result would include only “beta” and “gamma” keys with their respective values.
Conclusion
Creating a map from two lists of keys and values in Terraform enables more dynamic and readable configurations. From the straightforward zipmap
function to more complex mapping with conditional logic, Terraform provides the tools to efficiently organize and leverage your data. By understanding and applying these techniques, you can enhance your Terraform configurations to be more flexible and maintainable.