Mastering Terraform builtin functions  with examples

When I first started with Terraform to write configuration to deploy infrastructure on AWS and GCP, I did not know how powerful Terraform is. 

I wrote configuration code like an armature — repeated code blocks, hardcoded values, and bloated and inflexible infrastructure configuration code.

It took me a while to start using Terraform’s built-in functions, and everything changed. I learned to leverage Terraform functions in my configuration code. My terraform code got 10x more flexible, manageable, readable, scalable, and DRY.

In this blog post, I will talk about the most popular Terraform functions and where to use them with examples.

Let’s get started with Terraform functions

The Terraform language includes several built-in functions that you can call from within expressions to transform and combine values.

Note: The Terraform language does not support user-defined functions, and so only the functions built into the language are available for use.

The most commonly used Terraform function

Terraform list functions with examples

  • formatlist(): formatlist produces a list of strings by formatting a number of other values according to a specification string.

It’s particularly useful when you want to create a formatted string by combining elements from a list, and you want to apply a consistent formatting pattern to those elements.

locals {
fruits = ["apple", "banana", "orange"]
formatted_list = formatlist("I like %s.", local.fruits...)
}

output "formatted_list_output" {
value = local.formatted_list
}

-> formatted_list_output = [ "I like apple.", "I like banana.", "I like orange.",]

  • flatten(): flatten function transforms a nested list or nested tuple into a flat list.

This can be useful when you have a list of lists or a list of tuples, and you want to combine all the elements into a single flat list.

locals {
nested_list = [
["item1", "item2"],
["item3", "item4", "item5"],
["item6"],
]

flat_list = flatten(local.nested_list)
}

output "flat_list_output" {
value = local.flat_list
}

  • concat(): the concat function is used to concatenate two or more lists or strings together.

It’s commonly used when you want to combine multiple lists or strings into a single list or string.

variable "list1" {
default = ["a", "b", "c"]
}
variable "list2" {
default = ["d", "e", "f"]
}
variable "combined_list" {
value = concat(var.list1, var.list2)
}

  • element():function retrieves an element from a list at a specified index.
locals {
weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
third_weekday = element(local.weekdays, 2)
}
  • slice(): function extracts a sublist from a list, specifying a starting index and an optional ending index.
locals {
numbers = [1, 2, 3, 4, 5]
selected_numbers = slice(local.numbers, 1, 3)
}

Terraform map functions with examples

  • merge(): The merge function in Terraform is used to combine multiple maps into a single map.

merge(map1, map2, map3, …) -> merged_map

This function is useful when you want to aggregate configurations from multiple sources. It is mostly used to create flexible and modular configurations.

variable "base_config" {
type = map(string)
default = { key1 = "value1", key2 = "value2" }
}

variable "additional_config" {
type = map(string)
default = { key2 = "new_value2", key3 = "value3" }
}

output "extended_config" {
value = merge(var.base_config, var.additional_config)
}

  • lookup(): The lookup function in Terraform is used to safely access the value of a given key in a map. It returns the value associated with the specified key if it exists, or a default value if the key does not exist.

This function is particularly useful in scenarios where you want to dynamically fetch information from a map, especially when dealing with variable configurations and data structures.

variable "environment_vars" {
type = map(string)
default = {
dev = "dev-database-url"
prod = "prod-database-url"
}
}

variable "current_environment" {
type = string
default = "prod"
}

output "database_url" {
value = lookup(var.environment_vars, var.current_environment, "default-database-url")
}

In this example, the lookup function fetches the database URL based on the current environment. If the environment is not found in the map, it defaults to a predefined value.


  • zipmap(): zipmap function in Terraform is used to create a map by pairing elements from two separate lists

This function is particularly useful in scenarios where you have two lists that correspond to each other, and you want to construct a map associating elements from one list with elements from the other

variable "resource_names" {
type = list(string)
default = ["web", "db", "app"]
}

resource "aws_instance" "example" {
count = length(var.resource_names)
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = zipmap(["Name"], [var.resource_names[count.index]])
}

In this scenario, the zipmap is used to dynamically assign names to AWS instances based on the elements in the “resource_names” list.

variable "config_keys" {
type = list(string)
default = ["max_connections", "timeout", "retry_limit"]
}

variable "config_values" {
type = list(number)
default = [100, 30, 5]
}

output "application_config" {
value = zipmap(var.config_keys, var.config_values)
}

Here it is used for configuring application parameters.


  • length(): Returns the length of a list, string, or map.
  • keys(): Returns a list of keys from a map.
  • values(): Returns a list of values from a map.
variable "tags" {
type = map(string)
default = {
"Name" = "my-instance"
"Env" = "production"
"App" = "web"
}
}

locals {
tag_count = length(var.tags)
tag_keys = keys(var.tags)
tag_values = values(var.tags)
}

map(): map function transforms the values of a map using expressions.

locals {
prices = {
apple = 0.5
banana = 0.3
orange = 0.7
}
discounted_prices = map(
for fruit, price in local.prices : fruit => price * 0.9
)
}

Terraform string functions with example

  • format(): format functions allows you to create formatted strings by substituting values into placeholders.

In the below example format function is used to dynamically generate unique names for AWS instances.

variable "environment" {
type = string
default = "dev"
}

resource "aws_instance" "example" {
count = 3
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = format("instance-%s-%02d", var.environment, count.index + 1)
}
}

  • replace():function in Terraform is used to replace occurrences of a specified substring in a given string with another substring.

Syntax replace(string, search, replace)

variable "file_paths" {
type = list(string)
default = ["C:\\Users\\user1\\documents\\file1.txt", "D:\\Data\\file2.txt", "E:\\Projects\\file3.txt"]
}

output "standardized_file_paths" {
value = [for path in var.file_paths : replace(path, "\\", "/")]
}

# we used replace to standardize the file path

  • split(): split function to split a string into a list of substrings based on a specified delimiter.

This function is useful in scenarios where you need to extract or manipulate parts of a string within your Terraform configurations.


variable "user_emails" {
type = list(string)
default = ["user1@example.com", "user2@example.com", "user3@example.com"]
}

resource "aws_instance" "user_instances" {
count = length(var.user_emails)

ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"

tags = {
Name = replace(split("@", var.user_emails[count.index])[0], ".", "-")
}
}

In the above scenario, we have three user email addresses as input, and we’ll use the name part of each email address to create AWS EC2 instances with dynamically generated names.

We used the replace function to replace dots with hyphens in the names.


  • join(): function concatenates a list of strings into a single string, separated by a delimiter.
locals {
join_string = join(",", ["a", "b", "c"])
}

output "join_string" {
value = local.join_string
}

# output will be -> “a, b, c”.
terraform functions

That’s it for this blog post. I will cover more terraform functions in the upcoming blogs of this series.

Akhilesh Mishra

Akhilesh Mishra

I am Akhilesh Mishra, a self-taught Devops engineer with 11+ years working on private and public cloud (GCP & AWS)technologies.

I also mentor DevOps aspirants in their journey to devops by providing guided learning and Mentorship.

Topmate: https://topmate.io/akhilesh_mishra/