Functions
HCL includes a library of built-in functions for working with strings, numbers, collections, dates, and more.
Below are practical examples of common scenarios where HCL functions are useful in Terraform configurations.
Section titled “Below are practical examples of common scenarios where HCL functions are useful in Terraform configurations.”String Manipulation
Section titled “String Manipulation”HCL functions like upper(), lower(), replace(), and substr() allow you to transform and manipulate strings easily.
For instance, you can convert a string to uppercase, replace specific characters, or extract a substring.
locals { upper_case_str = upper("hello world") lower_case_str = lower("HELLO WORLD") replaced_str = replace("hashicorp terraform", "hashicorp", "HCL") substring_str = substr("terraform", 0, 4)}Mathematical Calculations
Section titled “Mathematical Calculations”Functions like min(), max(), ceil(), and floor() enable you to perform mathematical operations on numeric values.
You can calculate the minimum or maximum value, round numbers up or down, and much more.
locals { minimum_value = min(5, 10, 3) maximum_value = max(2, 8, 6) rounded_up = ceil(5.3) rounded_down = floor(7.9)}Iteration with Functions
Section titled “Iteration with Functions”While for (an expression) and count (a meta-argument) are not technically functions, they are commonly used alongside functions for iteration. The for expression lets you transform collections, and count lets you create multiple resource instances.
These are covered in detail in the Loops section.
resource "aws_instance" "example" { count = length(var.instance_types)
instance_type = var.instance_types[count.index]}
output "instance_types_upper" { value = [for i in var.instance_types : upper(i)]}Filesystem Functions
Section titled “Filesystem Functions”Terraform provides a set of filesystem functions that enable you to interact with files and directories. For instance,
the file() function allows you to read the contents of a file and use it in your Terraform configuration. You can
leverage this function to load configuration data from external files or pass file contents as inputs to resources.
locals { file_content = file("${path.module}/example.txt")}Date and Time Functions
Section titled “Date and Time Functions”HCL functions offer capabilities to work with dates, times, and durations. The timestamp() function returns the current
timestamp, while formatdate() allows you to format a timestamp into a specific date or time format. You can perform date
arithmetic using functions like timeadd() to calculate durations or add/subtract time from timestamps.
locals { current_time = timestamp() formatted_time = formatdate("YYYY-MM-DD", timestamp()) time_after_1_hour = timeadd(timestamp(), "1h")}Collection Functions
Section titled “Collection Functions”Terraform provides various functions to work with lists and maps. The length() function allows you to determine the
length of a list or map. You can extract specific elements from a list using element() or slice().
The keys() and values() functions help you retrieve the keys and values of a map, respectively. These functions enable
you to manipulate and transform collections to fit your infrastructure requirements.
locals { my_list = ["apple", "banana", "cherry"] list_length = length(local.my_list) second_element = element(local.my_list, 1) sliced_list = slice(local.my_list, 0, 2)
my_map = { "key1" = "value1", "key2" = "value2" } map_keys = keys(local.my_map) map_values = values(local.my_map)}Encoding and Decoding Functions
Section titled “Encoding and Decoding Functions”HCL functions include functions for encoding and decoding data formats like Base64. The base64encode() function allows
you to encode data to Base64 format, while base64decode() decodes Base64-encoded data. These functions come in handy
when working with secrets or manipulating data in specific formats.
locals { encoded_value = base64encode("my-secret-value") decoded_value = base64decode("bXktc2VjcmV0LXZhbHVl")}Provider-Defined Functions
Section titled “Provider-Defined Functions”Starting with Terraform 1.8, providers can ship their own functions alongside resources and data sources. These provider-defined functions are compiled into the provider plugin (written in Go) and extend Terraform’s capabilities beyond what the core built-in functions offer.
Syntax
Section titled “Syntax”Provider-defined functions follow a namespaced calling convention:
provider::provider_name::function_name(arguments)The double-colon separators distinguish provider functions from built-in functions, making it clear where the logic lives.
Declaring the Provider
Section titled “Declaring the Provider”Before you can call a provider-defined function, the provider must be declared in your required_providers block — even
if you are not creating any resources with it:
terraform { required_providers { aws = { source = "hashicorp/aws" version = ">= 5.40.0" } }}AWS Provider Examples
Section titled “AWS Provider Examples”The AWS provider includes functions for working with ARNs. provider::aws::arn_parse() breaks an ARN string into its
component parts, and provider::aws::arn_build() constructs an ARN from individual fields:
locals { # Parse an ARN into its components parsed = provider::aws::arn_parse("arn:aws:iam::123456789012:role/my-role")
# parsed.partition = "aws" # parsed.service = "iam" # parsed.region = "" # parsed.account_id = "123456789012" # parsed.resource = "role/my-role"}
output "role_account" { value = local.parsed.account_id}locals { # Build an ARN from individual components bucket_arn = provider::aws::arn_build({ partition = "aws" service = "s3" region = "" account_id = "" resource = "my-bucket" })
# Result: "arn:aws:s3:::my-bucket"}How They Differ from Built-In Functions
Section titled “How They Differ from Built-In Functions”Built-in functions are part of the HCL language itself and are available in every Terraform project without any additional configuration. Provider-defined functions, on the other hand:
- Are compiled into the provider plugin and written in Go
- Require the provider to be declared in
required_providers - Use the
provider::name::function()namespace to avoid collisions with built-in functions - Extend Terraform’s capabilities with domain-specific logic that would not belong in the core language
This means providers can offer specialised helpers — like ARN parsing, policy validation, or encoding utilities — without waiting for changes to Terraform itself.
Experimenting with HCL Functions
Section titled “Experimenting with HCL Functions”A quick way to experiment with HCL functions, and more generally testing out manipulating resources, variables within a Terraform project is to use Terraform console. The console requires an initialised project, and allows testing of terraform functions and interaction with resources within the project.
terraform consoleConclusion
Section titled “Conclusion”This section walked through common function categories — string manipulation, maths, collections, encoding, filesystem, and date/time. For a complete list, check the function reference. The quickest way to try things out is terraform console, where you can test any function interactively against your current project.