How to Concatenate Strings in Terraform Using the concat Function
The terraform concat function merges multiple lists into a single list, requiring the join function to flatten the resulting elements into a single concatenated string.
In the hashicorp/terraform repository, string concatenation is handled as a two-stage operation because the built-in concat function operates exclusively on list types. While many users search for terraform concat expecting direct string joining, the actual implementation in language/functions/concat.go reveals that this function returns a list type, making it the first step in assembling complex strings from dynamic parts.
Why terraform concat Returns Lists
According to the source code in language/functions/concat.go, the concat function is designed to combine multiple lists into a single sequence while preserving the element type. The function is registered in language/functions/function_registry.go alongside other built-in list operations. When you call concat, Terraform validates that all arguments are lists or tuples and returns a new list containing all elements in order.
This list-only behavior means you cannot pass raw strings directly to concat. Attempting to do so will result in a type error during the validation phase.
The String Concatenation Pattern: concat Plus join
To build strings using terraform concat, you must follow a three-step workflow:
- Create lists of string fragments using literals or variables
- Merge the lists with
concatif combining multiple sources - Convert to a string using
joinfromlanguage/functions/join.go
Basic String Building
For a single list of fragments, you can skip the explicit concat call and use join directly:
locals {
parts = ["Hello", " ", var.name, "!"]
}
output "greeting" {
value = join("", local.parts)
}
This produces a single string like "Hello World!" by joining the list elements with an empty separator.
Merging Multiple Lists
When combining fragments from different sources, concat becomes necessary before the final join:
locals {
prefix = ["User:", " "]
name = [var.username]
suffix = [" (admin)"]
}
output "full_label" {
value = join("", concat(local.prefix, local.name, local.suffix))
}
In this example, concat(local.prefix, local.name, local.suffix) merges three distinct lists into one, which join then converts into "User: alice (admin)".
Conditional Fragment Assembly
The terraform concat function excels when programmatically assembling parts based on conditions:
locals {
parts = concat(
["Base"],
var.enable_extra ? ["+extra"] : []
)
}
output "conditional_string" {
value = join("", local.parts)
}
This pattern returns "Base+extra" when var.enable_extra is true, otherwise returning just "Base".
Alternative: Interpolation Syntax
For simple cases requiring no list manipulation, Terraform’s interpolation syntax provides a more direct approach than the concat/join pattern:
output "simple_greeting" {
value = "Hello ${var.name}!"
}
While interpolation works for static templates, the concat and join combination from language/functions/join.go offers greater flexibility when dealing with dynamic list lengths or conditional elements.
Source Code Implementation
The hashicorp/terraform repository contains the following key files governing this behavior:
language/functions/concat.go: Contains the core logic that merges multiple lists into a single list, performing type checking and element ordering.language/functions/join.go: Implements the string conversion function that takes a list (often fromconcat) and separator to produce the final string.language/functions/function_registry.go: Registers bothconcatandjoinas built-in functions available in HCL expressions.docs/language/functions/concat.html: Provides the official documentation describing the function's list-only return type and usage patterns.
Summary
terraform concatmerges lists, not raw strings, returning a combined list类型 as implemented inlanguage/functions/concat.go.- Use
jointo stringify: Pass the result ofconcattojoinwith an empty separator""to create a single concatenated string. - Skip concat for single lists: If you have only one list of fragments, call
joindirectly without intermediateconcatlogic. - Interpolation for simple cases: Use
"${var.a}${var.b}"syntax instead ofconcat/joinfor fixed, simple concatenations.
Frequently Asked Questions
Can terraform concat directly concatenate strings?
No. According to the implementation in language/functions/concat.go, the concat function accepts only list or tuple arguments and returns a list. To concatenate strings, you must first place them in lists, optionally merge those lists with concat, then pass the result to the join function to produce a string.
What is the difference between concat and join in Terraform?
The concat function (defined in language/functions/concat.go) operates on lists and returns a combined list containing all elements from its arguments. The join function (in language/functions/join.go) specifically converts a list of strings into a single string using a specified separator. For string concatenation, you typically use concat to assemble list elements and join to render the final string.
How do I concatenate strings with a separator in Terraform?
Use the join function with a non-empty separator argument: join(", ", local.parts). If local.parts contains multiple lists that need merging first, wrap them in concat: join(", ", concat(list_a, list_b)). The separator is the first argument to join, as documented in the source at language/functions/join.go.
Where is the concat function implemented in the Terraform source code?
The concat function implementation resides in language/functions/concat.go within the hashicorp/terraform repository. This file contains the Function definition that Terraform registers in language/functions/function_registry.go, along with the logic for validating list arguments and returning the merged sequence.
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