How to Use Terraform coalesce to Replace null Values with Default Values
Terraform's coalesce function returns the first non-null argument from a list of values, making it the standard way to provide fallback defaults when variables or expressions might be null.
The coalesce function is a built-in utility in the HashiCorp Terraform expression language that solves the common problem of nullable inputs. When working with the hashicorp/terraform codebase, you'll find this function implemented as a native HCL function that evaluates arguments sequentially until it finds the first non-null value.
What Is Terraform coalesce?
coalesce is a built-in function that accepts one or more arguments and returns the first one that is not null. If all arguments evaluate to null, the function returns null. This behavior makes it ideal for creating fallback chains where you want to use a computed value if available, but substitute a default when that value is absent.
In the Terraform source code, the coalesce function is implemented in Go within internal/lang/functions/coalesce.go. The runtime checks each argument sequentially and returns the first non-null result, exactly matching the documented behavior in the language reference.
Basic Syntax and Behavior
The function signature accepts a variable number of arguments:
coalesce(value1, value2, ..., valueN)
Terraform evaluates the arguments from left to right. When it encounters the first argument that is not null, it returns that value immediately without evaluating subsequent arguments. If you pass multiple potential sources ending with a hard-coded default, you create a reliable fallback mechanism.
locals {
# Returns "default" if var.maybe_null is null
result = coalesce(var.maybe_null, "default")
}
Practical Examples of Terraform coalesce
Providing Default Values for Variables
When you define a variable that accepts null to indicate "use system defaults," coalesce lets you substitute a practical default at the resource level:
variable "instance_type" {
type = string
default = null
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = coalesce(var.instance_type, "t3.micro")
}
If var.instance_type is left unset or explicitly set to null, the instance launches as t3.micro.
Handling Nullable Data Source Attributes
Data sources sometimes return null for attributes that don't exist in the queried infrastructure. You can chain multiple fallback options:
data "aws_subnet" "selected" {
filter {
name = "tag:Name"
values = ["frontend"]
}
}
locals {
subnet_id = coalesce(
data.aws_subnet.selected.id,
var.fallback_subnet_id,
"subnet-0123456789abcdef0"
)
}
The first non-null subnet ID is used, falling back to a variable or a hard-coded ID only when necessary.
Chaining Multiple Optional Inputs
For standardizing tags across modules where multiple optional inputs might exist:
locals {
# Prefer a custom tag, otherwise use the environment tag,
# otherwise fall back to "unknown".
owner_tag = coalesce(
var.custom_owner_tag,
var.environment_owner_tag,
"unknown"
)
}
This pattern ensures consistent tagging even when individual variables are omitted.
How coalesce Works Under the Hood
The implementation in internal/lang/functions/coalesce.go defines the function as part of Terraform's native HCL function library. The Go code evaluates each argument sequentially using the HCL type system, returning the first value that is not a null type.
Function registration occurs in internal/lang/functions/function.go, where coalesce is added to the global function table available during expression evaluation. When Terraform parses your configuration during the plan or apply phase, the expression evaluator invokes this registered function, executing the logic defined in the coalesce implementation.
The official documentation in docs/language/functions/coalesce.html.markdown provides the user-facing contract that mirrors this runtime behavior, ensuring consistency between documented functionality and actual execution.
Summary
coalescereturns the first non-null argument from a variable-length argument list, making it the standard pattern for default value substitution in Terraform.- The function is implemented in
internal/lang/functions/coalesce.goand registered ininternal/lang/functions/function.gowithin the HashiCorp Terraform repository. - You can chain multiple fallback values, ending with a hard-coded default to ensure a valid value is always available.
coalesceonly checks fornullvalues; empty strings, zero values, and false booleans are considered valid and will be returned immediately.
Frequently Asked Questions
What happens if all arguments to coalesce are null?
If every argument passed to coalesce evaluates to null, the function returns null. This behavior allows you to chain multiple coalesce calls or handle the null case separately using conditional logic.
Can coalesce handle empty strings or zero values?
No. The coalesce function specifically checks for null values only. Empty strings (""), the number 0, false, and empty lists or maps are considered valid non-null values and will be returned immediately if they appear as the first argument.
How does coalesce differ from the try function?
While coalesce checks for null values, the try function catches and suppresses errors during evaluation. Use coalesce when you want to skip null results but preserve error conditions; use try when you want to ignore errors and return a fallback value.
Is there a performance cost to using coalesce?
The performance impact is negligible. According to the implementation in internal/lang/functions/coalesce.go, the function performs a simple sequential scan of arguments, returning immediately upon finding the first non-null value. No complex computation or external I/O occurs during evaluation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s https://instagit.com/install.md