How to use Terraform Merge Function: Tips, Examples, and Best Practices

Estimated reading time: 8 minutes

Last updated on November 8th, 2024 at 01:08 pm

The Terraform merge function is powerful for combining multiple objects or mapping into a single object. This Terraform merge function is useful in various complex configurations where the data mrgeing from different source is essential.

In this guide, we’ll learn everything you need to know about the Terraform merge function, including syntax examples, best practices, and common troubleshooting tips for making the most out of it.

Understanding the Terraform Merge Function

What Is the Terraform Merge Function?

The Terraform merge function takes two or more map objects and returns the combined output out single map.

It’s particularly helpful for the CI/CD and infrastructure as Code (IaC) use cases, where configuration management is required to aggregate the environment-specific settings and provide configurations.

Let’s check the syntax structure:

Syntax:

HCL
merge(map1, map2, map3, ...)

As you can see the map function allows you to pass multiple maps to merge in a single object.

What happens when the duplicate keys are found? If there are duplicate keys are found then the values from the rightmost map take priority precedence.

When to Use the Merge Function in Terraform

As mentioned, merge function can help simplify configuration management by combining variables and settings from multiple input sources.

Let’s check some common use cases when you should use it:

  • Managing multi-environment setups by merging environment-specific variables.
  • Modular code structure where common / default settings are centralized and overridden if needed.
  • Dynamic or conditional settings for the provider configurations.

How to Use Terraform Merge Function with Examples

Basic Syntax and Parameters of Merge

Example 1: Merging Two Simple Maps
HCL
variable "map1" {
  default = {
    environment = "development"
    region      = "us-east-1"
  }
}

variable "map2" {
  default = {
    region = "us-west-2"
    owner  = "devops_team"
  }
}

output "merged_map" {
  value = merge(var.map1, var.map2)
}

Result:

HCL
{
  environment = "development"
  region      = "us-west-2"
  owner       = "devops_team"
}

Here, the region value from map2 overwrites the region in map1, shows how merge handles duplicate keys by prioritizing the rightmost map.

Example 2: Merging Maps with Unique Keys
HCL
variable "map1" {
  default = {
    project = "terraform-merge"
  }
}

variable "map2" {
  default = {
    cost_center = "001145"
  }
}

output "merged_map" {
  value = merge(var.map1, var.map2)
}

Result:

HCL
{
  project     = "terraform-merge"
  cost_center = "001145"
}

In this case, there are no overlapping or duplicating keys between map1 and map2, hence both key-value pairs are included in the final merged map.

Example 3: Merging Multiple Maps with Overlapping Keys
HCL
variable "map1" {
  default = {
    env = "prod"
    instance_type = "t2.micro"
  }
}

variable "map2" {
  default = {
    instance_type = "t2.medium"
    region        = "us-east-1"
  }

variable "map3" {
  default = {
    region = "us-west-1"
    owner  = "ops_team"
  }
}

output "merged_map" {
  value = merge(var.map1, var.map2, var.map3)
}

Result:

HCL
{
  env           = "prod"
  instance_type = "t2.medium"
  region        = "us-west-1"
  owner         = "ops_team"
}

The final values for instance_type and region are taken from the last maps (map2 and map3), showing how the order affects which values are retained.

Example 4: Terraform Merge Lists

Terraform provides a way to manage the structure code with the merge lists. Terraform merge lists combine multiple values and lists into one with the aggregate list.

I’ve already written a detailed article about the “Terraform Merge Lists: Effective Use” with practical examples.

Advanced Example: Merging Nested Maps and Complex Data Structures

When working with nested maps or more complex structures, understanding how merge to handle key conflicts is essential.

Example 1: Merging Maps with Nested Structures
HCL
variable "map1" {
  default = {
    metadata = {
      env = "staging"
    }
  }
}

variable "map2" {
  default = {
    metadata = {
      env  = "production"
      team = "engineering"
    }
  }
}

output "merged_nested_map" {
  value = merge(var.map1, var.map2)
}

Result:

HCL
{
  metadata = {
    env  = "production"
    team = "engineering"
  }
}

Let’s understand the above output, here the entire metadata block from map2 overwrites the one in map1, as merge does not perform deep merging.

Example 2: Deep Merge Alternative

Terraform supports merging but deep merging is a special case.

Deep merging is considered when you provide 2 or more maps of the object and have the same recursive structure to find the duplicate and override the values.

Unfortunately, Terraform does not natively support it, but custom modules or functions can be used to achieve the effect.

You can chain merge calls manually or use custom scripts to merge nested elements.

Best Practices and Common Pitfalls with Terraform Merge

Key Overwrite Rules and Precedence

The Terraform merge function prioritizes the values in the last map passed as an argument. You can see the example we’ve checked in the basic example sections.

Terraform can handle the duplication keys effectively but this can lead to unintended overwrites if not carefully managed. To ensure accuracy:

  • Order the maps carefully to avoid unintended overwrites.
  • Document the precedence logic in your configuration, especially for shared configurations.

You can check out the important article about writing the document in your configuration with the Terraform Comment Block: A Comprehensive Guide to Avoid Issues with Shared Configuration.

Troubleshooting Errors with the Merge Function

Common issues with merge often involve type mismatches, where data types do not align across maps.

To avoid these errors:

  1. Consistent types: Each element passed to merge should have compatible data structures.
  2. Use try function for error handling: This can help gracefully handle missing or unexpected values.

Terraform Coalesce vs Try: Error Handling with Practical Examples

Example: Handling Errors with try and merge

HCL
variable "map1" {
  default = {
    env = "development"
  }
}

output "error_handle" {
  value = try(merge(var.map1, var.map2), "Error: map2 not defined")
}

In this example, if map2 is not defined, Terraform will output an error message instead of failing, using try as a safeguard.

Combining Merge with Other Terraform Functions

The Terraform merge function works perfectly with other functions like coalesce and flatten for more versatile configurations.

Terraform Coalesce vs Try: Error Handling with Practical Examples

For example, using coalesce ensures that non-null values are merged in priority.

Example: Using Merge with Coalesce

HCL
variable "defaults" {
  default = {
    env = "test"
  }
}

variable "overrides" {
  default = {
    env = null
  }
}

output "final_env" {
  value = coalesce(merge(var.defaults, var.overrides).env, "default_env")
}

In this case, coalesce uses the non-null env value, giving preference to defaults when overrides is null.

Terraform Merge Function Use Cases

Dynamic Environment Variables and Map Merging

Let’s take the real work example where you can use the Terraform merge function for the dynamic environment, configuration simplifies setting up variables across development, staging, and production.

HCL
variable "default_env" {
  default = {
    DB_NAME = "mydb"
    DB_PORT = "23306"
  }
}

variable "production_env" {
  default = {
    DB_PORT = "43306"
    DB_USER = "admin"
  }
}

output "env_variables" {
  value = merge(var.default_env, var.production_env)
}

In this example, the DB_PORT variable is set to the production-specific value, while other variables default to default_env.

Merging Provider Configurations for Modular Infrastructure

For modular projects, merging maps enables consolidating provider settings or common configurations.

HCL
variable "default_settings" {
  default = {
    region = "us-west-1"
    version = "~> 3.0"
  }
}

variable "override_settings" {
  default = {
    region = "us-east-1"
  }
}

output "final_settings" {
  value = merge(var.default_provider, var.override_provider)
}

In this setup, region is overridden, providing a flexible approach to managing configuration.

FAQs

How does the merge function handle overlapping keys in maps?

if two or more maps contain the same key, the value from the last map listed will override the previous ones.

For example, if merge({x = 1}, {x = 2}) is used, the result will be {x = 2} because the second map’s value takes precedence.

This behavior makes it easy to apply environment-specific or deployment-specific overrides, ensuring that your final configuration has the most relevant settings.

Can I use merge to combine more than two maps in Terraform?

Yes, the merge function in Terraform can accept multiple maps, not just two. Simply list all maps you want to combine as arguments to merge, separated by commas.

For example, merge(map1, map2, map3) will produce a single map that includes all key-value pairs from each map, with precedence given to values from later maps in the list.

Conclusion

The Terraform merge function is essential for managing complex configurations by simplifying map configuration.

In the article, we learn that by understanding its syntax, key precedence, and use with other functions, you can easily manage configurations, prevent redundancies, and handle data dynamically across environments.

Use the Terraform merge function in your workflow for maintainable IaC configuration and organize the infrastructure as it grows.

Read More Articles:

Kashyap Merai

Kashyap Merai

Kashyap Merai, a Certified Solution Architect and Public Cloud Specialist with over 7 years in IT. He helped startups in Real Estate, Media Streaming, and On-Demand industries launch successful public cloud projects.

Passionate about Space, Science, and Computers, He also mentors aspiring cloud engineers, shaping the industry's future.

Connect with him on LinkedIn to stay updated on cloud innovations.