Terraform Built-in Functions: Format, Merge, File & More
Terraform built-in functions are expressions that transform, combine, and manipulate values, enabling dynamic and flexible configurations without external tools or scripts.
What You'll Learn
In this tutorial, you will learn how to use Terraform built-in functions for string formatting, collection manipulation, file operations, type conversion, and numeric computation to write expressive configurations.
Why It Matters
Functions eliminate hardcoded values and manual string concatenation. They let you generate resource names, merge tag maps, read files for user data scripts, and transform data structures -- all within Terraform's declarative model.
Real-World Use
DodaTech uses the format function for consistent resource naming, merge for combining default and environment-specific tags, and file for loading CloudFormation templates and user data scripts into Durga Antivirus Pro's EC2 instances.
String Functions
Format
The format function produces formatted strings using printf-style syntax:
locals {
name_prefix = "dodatech"
environment = "production"
instance_name = format("%s-%s-web-01", local.name_prefix, local.environment)
db_identifier = format("db-%s-%s", local.name_prefix, local.environment)
}
output "names" {
value = {
instance = local.instance_name
database = local.db_identifier
}
}
Expected output:
names = {
database = "db-dodatech-production"
instance = "dodatech-production-web-01"
}
Join and Split
locals {
security_groups = ["sg-12345", "sg-67890", "sg-abcde"]
sg_list = join(", ", local.security_groups)
sg_arn = format("arn:aws:ec2:us-east-1:123456789012:security-group/%s", local.sg_list)
}
output "security_group_arn" {
value = local.sg_arn
}
Expected output:
security_group_arn = "arn:aws:ec2:us-east-1:123456789012:security-group/sg-12345, sg-67890, sg-abcde"
Lower, Upper, and Title
locals {
raw_name = "DODA-TECH-WEB-SERVER"
clean = lower(local.raw_name)
title = title(local.clean)
}
output "formatted" {
value = {
original = local.raw_name
lower = local.clean
title = local.title
}
}
Expected output:
formatted = {
lower = "doda-tech-web-server"
original = "DODA-TECH-WEB-SERVER"
title = "Doda-Tech-Web-Server"
}
Collection Functions
Merge
Combines multiple maps into one, with later maps overriding earlier keys:
locals {
default_tags = {
ManagedBy = "Terraform"
Project = "DodaTech"
}
environment_tags = {
Environment = "production"
CostCenter = "Infrastructure"
}
all_tags = merge(local.default_tags, local.environment_tags, {
Name = "web-server"
})
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = local.all_tags
}
Expected output: The instance has four tags: ManagedBy, Project, Environment, CostCenter, and Name. The merge order ensures environment tags override defaults.
Flatten
Converts nested lists into a flat list:
locals {
cidr_blocks = flatten([
["10.0.1.0/24", "10.0.2.0/24"],
["10.0.3.0/24", "10.0.4.0/24"],
])
}
output "flat_cidrs" {
value = local.cidr_blocks
}
Expected output:
flat_cidrs = [
"10.0.1.0/24",
"10.0.2.0/24",
"10.0.3.0/24",
"10.0.4.0/24",
]
File Function
The file function reads the contents of a file at the given path:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
user_data = file("${path.module}/scripts/bootstrap.sh")
}
Expected output: Terraform reads scripts/bootstrap.sh relative to the current module directory and passes its contents as user data to the EC2 instance.
Templatestring with File
locals {
environment = "production"
app_version = "2.5.1"
user_data = templatefile("${path.module}/templates/user_data.tftpl", {
env = local.environment
version = local.app_version
})
}
Expected output: Reads a template file, replaces ${env} and ${version} placeholders with the local values, and returns the rendered string.
Numeric Functions
locals {
desired_capacity = 4
max_capacity = 10
min_capacity = 2
# Ensure values stay within bounds
safe_desired = max(local.min_capacity, min(local.desired_capacity, local.max_capacity))
}
output "auto_scaling_config" {
value = {
min = local.min_capacity
max = local.max_capacity
desired = local.safe_desired
}
}
Expected output:
auto_scaling_config = {
desired = 4
max = 10
min = 2
}
Common Mistakes
1. Forgetting Function Parentheses
Terraform functions always require parentheses: lower("HELLO") not lower "HELLO".
2. Passing Wrong Types
Using merge with lists or flatten with maps causes type errors. Verify function signatures in the Terraform documentation.
3. File Path Resolution
The file function uses paths relative to the current module. Using absolute paths or paths outside the module directory causes errors.
4. Template Syntax Conflicts
Using ${} inside template files for non-Terraform purposes (like shell variables) causes interpolation errors. Escape with $${}.
5. Nested Function Readability
Deeply nested function calls like merge(lookup(var.config, "tags", {}), var.default_tags, ...) are hard to read. Use intermediate locals.
Practice Questions
1. What does the merge function do?
Combines multiple maps into one. Later maps override keys from earlier maps.
2. How do you read a file into a Terraform configuration?
Use the file function: file("${path.module}/filename.txt").
3. What is the difference between format and join?
format creates a string with printf-style formatting. join concatenates list elements with a separator.
4. How does the templatefile function differ from file?
file reads raw content. templatefile reads content and renders template variables with values from a map.
5. Challenge: Write a configuration that uses format, merge, file, flatten, and max/min functions to create resource names, tags, user data, subnet lists, and scaling constraints.
Mini Project: Function-Driven Configuration
Create a configuration that reads a user-data template from a file, merges default and environment tags, formats resource names, flattens subnet CIDR lists from a nested variable, and clamps scaling values within bounds.
Related Concepts
What's Next
Use Terraform built-in functions to write dynamic configurations, then learn Terraform Import to bring existing infrastructure under IaC management.
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro