Terraform Map Variable: How to Define, Access, and Use It in Real Projects

Chafik Belhaoues

Terraform map variable is one of the most versatile data structures in Terraform configurations. Maps allow you to store key-value pairs, which makes infrastructure code dynamic and reusable. Proper use of Terraform map variables is critical when managing complex environments, from dev environments to production clusters with hundreds of resources. In this article, we will discuss how to declare, access, and apply map variables in real projects. For visual design and management of Terraform configurations, we recommend the Brainboard platform, which simplifies working with complex data structures.

What Is a Terraform Map Variable?

A Terraform map is a collection of key-value pairs, where each key is a unique string mapped to a specific value. Unlike strings, numbers, and lists, a Terraform map allows you to group related parameters under a single variable. For example, instead of three separate variables for region, instance type, and environment name, you can combine them into a single map.

Map values can be:

  • string
  • number
  • boolean values (bool)
  • nested objects and lists

When values have different types or a nested structure, the Terraform map object is used—a more strictly typed form in which a specific type is specified for each key. This allows Terraform to validate input data at the plan stage and prevent errors before applying changes.

How to Define and Access Terraform Map Variables

The Terraform map declaration begins with a variable block specifying the type, description, and default value:

variable “instance_settings” {

  description = “Settings per environment”

  type = map(string)

  default = {

    dev = “t3.micro”

    staging = “t3.small” prod = “t3.large”

  }

}

For more complex cases, use a Terraform map object with nested attributes:

variable “environments” {

  type = map(object({

    instance_type = string

    instance_count = number

    enable_monitoring = bool

  }))

}

There are several ways to pass map values:

  • through .tfvars
  • files through command line flags (-var)
  • through environment variables (TF_VAR_...)

There are two methods for accessing values. The first is bracket notation: var.instance_settings[“dev”]. The second is the lookup function with a fallback value: lookup(var.instance_settings, ‘dev’, “t3.micro”). The lookup function is safer because it allows you to set a default value if the key is missing, preventing the configuration from failing with an error.

Working with Terraform Map Functions

Terraform map functions greatly expand the possibilities of working with maps. Here are the key functions:

  • merge — merges two or more maps into one. If the keys match, the values from the last map overwrite the previous ones: merge(var.default_tags, var.env_tags).
  • lookup — retrieves a value by key with the option to specify a default value: lookup(var.regions, “eu-west-1”, “us-east-1”).
  • keys — returns a list of all map keys. This is the main way Terraform gets keys from a map: keys(var.instance_settings) returns [“dev”, “staging”, “prod”].
  • values — returns a list of all map values, useful for passing to loops or conditional logic.
  • zipmap — creates a map from two lists (keys and values): zipmap([“name”, ‘env’], [“web-server”, “prod”]).

These functions are especially useful when building dynamic configurations. The Brainboard platform provides a visual interface where you can design your architecture and immediately see how functions process map data.

Using Terraform List of Maps for Complex Configurations

A Terraform list of maps is a list where each element is a map with key-value pairs. This Terraform map type is indispensable when you need to describe several resources of the same type with different parameters.

Typical use cases:

  • defining multiple EC2 instances with different types and availability zones
  • configuring security group rules with different ports and CIDR blocks
  • creating DNS records with unique names and values

Iteration over a Terraform list of maps is performed using for_each or count:

variable “servers” {

  type = list(map(string))

  default = [

    { name = “web”, type = “t3.small” },

    { name = ‘api’, type = “t3.medium” }

  ]

}

resource “aws_instance” “server” {

  count = length(var.servers)

  instance_type = var.servers[count.index][‘type’]

  tags = {

    Name = var.servers[count.index][“name”]

  }

}

There are specialized tools for working with this kind of infrastructure code more conveniently. Brainboard lets you visualize resources and their dependencies, simplifying debugging complex configurations with nested structures.

Real-World Use Cases for Terraform Map Variables

In practice, Terraform values in a map format solve several tasks:

  • Environments. A single map stores parameters for dev, staging, and prod: instance types, replica count, and logging settings. Switching environments is done by replacing a single key.
  • Tagging strategy. A map of tags (merge common and specific) provides uniform resource labeling for cost accounting and auditing.
  • Multi-regional deployments. A map with region keys and configuration values lets you deploy infrastructure across multiple regions from a single module.
  • Dynamic module inputs. Maps are passed as module input variables, allowing you to reuse a single module for different scenarios.

This approach reduces code duplication and makes configurations scalable. For teamwork on Terraform projects, it is convenient to use Cloud Architecture Designer, where all participants can view the current architecture and jointly edit configurations.

Common Mistakes and Best Practices

When working with map variables, teams often make mistakes:

  • Lack of type constraint. Without explicitly specifying the type, Terraform accepts any value, leading to elusive errors. Always specify the type.
  • Inconsistent key names. Mixing camelCase and snake_case makes reading difficult. Stick to a consistent style.
  • Referencing non-existent keys. Using bracket notation without checking will cause an error. Use lookup with a default value or the try function.
  • Excessive nesting. Deeply nested Terraform map objects complicate maintenance. If nesting exceeds two levels, it is worth breaking the structure down into separate variables.
  • Lack of default values. Always set defaultso that the configuration remains functional when partially filled. To validate input data, use validation blocks with your own rules.

Mastering Terraform Maps for Scalable Infrastructure

Terraform map is a fundamental tool for writing clean, reusable, and scalable infrastructure code. Understanding the difference between a simple map and a Terraform map object, confidently using the merge, lookup, and keys functions, and working with map lists allows you to build flexible configurations of any complexity. Start with small examples and gradually apply maps to more complex projects. To speed up your work, use Brainboard, a platform that combines visual design with Terraform code generation.

FAQ

1. What is the difference between a Terraform map and a Terraform map object? 

A regular map (map(string)) contains values of a single type. A map object (map(object({...}))) allows different types for each attribute within a value, which makes it possible to describe complex nested structures.

2. How do I access a specific value from a Terraform map variable? 

There are two ways: bracket notation var.my_map[“key”] and the function lookup(var.my_map, ‘key’, “default_value”). The second option is safer for undefined keys.

3. Can I merge two or more maps in Terraform? 

Yes, the function merge(map1, map2, map3) combines multiple maps. If the keys match, the last map in the argument list takes priority.

4. How do I iterate over a Terraform list of maps using for_each? 

Convert the list to a map using for_each = { for idx, item in var.list : idx => item }, then access the attributes via each.value[“key”].

5. What happens if I try to access a key that does not exist in a Terraform map? 

When using bracket notation, Terraform will return an error. The lookup function with a third argument returns the specified default value, and the try function provides more flexible handling of missing keys.