How to Use Terraform Functions to Create Dynamic and Flexible Infrastructure

Exploring Key Functions and Real-World Use Cases for Effective Terraform Configuration

Ink Insight 🧘🏼
DevOps Dudes
4 min readJun 6, 2023

--

I discovered myself using various helpful methods to optimize my configuration while I worked on my current infrastructure deployment using Terraform.

Powerful features are available in Terraform functions for handling optional values, string manipulation, map lookups, and more.

I’ll explain in this blog post how I used each of these features in my Terraform configuration. Learn how functions such as coalesce(), join(), lookup(), format(), and element() may improve the provisioning and configuration of your infrastructure.

Let’s now examine each function’s specifics and see how they might be used to create more reliable and effective infrastructure settings.

Function 1

Function: coalesce()
Description: The coalesce() function returns the first non-null argument from a list of arguments.

Use case: When dealing with optional or conditional values, coalesce() helps provide a default value when the desired value is not available.

locals {
fallback_value = "default"
optional_value = null
result = coalesce(local.optional_value, local.fallback_value)
}

In my infrastructure, I had a scenario where I needed to handle optional input variables. Let’s say one of the input variables, optional_value, could be null or have a specific value. However, I wanted to ensure that I always have a valid value to work with.

This approach allowed me to provide a default value and ensure the presence of a valid value for further processing within my Terraform configuration. The coalesce() function played a crucial role in handling optional values effectively.

Function 2

Function: join()
Description: The join() function joins multiple strings into a single string using a specified separator.

Use case: Combining strings with separators is commonly used when constructing file paths, generating configuration strings, or creating command-line arguments.

resource "aws_instance" "example" {
count = 3
instance_type = "t3.micro"
name = join("-", ["web", "app", count.index + 1, var.environment])
}

I needed to create multiple instances of a particular resource, each with a unique name that included static values and variable inputs. By using the `join()` function, I combined the static strings “web”, “app”, and the index value of the current instance (incremented by 1) with a hyphen separator. Additionally, I included the value of the “environment” variable to differentiate instances based on the environment.

Function 3

Function: lookup()
Description: The lookup() function looks up a value in a map based on a given key.

Use case: Looking up values in a map is helpful when you need to retrieve specific configuration values based on keys.

locals {
environment_vars = {
"dev" = "development"
"prod" = "production"
}

current_environment = "prod"
environment_type = lookup(local.environment_vars, local.current_environment, "unknown")
}

I used it to retrieve the environment type based on the current environment. By using the lookup() function, I searched for the value associated with the current_environment key in the environment_vars map. If the key was found, the corresponding value was assigned to environment_type. If the key was not found, I provided a default value of “unknown”.

Function 4

Function: format()
Description: The format() function is used to format a string based on a given format specifier.

Use case: Formatting strings is useful when you need to generate dynamic resource names or construct complex output strings.

resource "aws_s3_bucket" "example" {
count = 3
bucket = format("my-bucket-%02d", count.index + 1)
}

We have so many functions which we can use to achieve similar things I used this format() function to create multiple S3 buckets with sequentially numbered names. By using the format() function, I constructed the bucket name by combining the static string “my-bucket-” with the index value. This is similar to what we did with join() function.

Function 5

Function: element() [element(list, index)]
Description: The element() function retrieves the element at a specific index from a list.

Use case: Accessing a specific element in a list is useful when you want to select a particular resource or parameter from a list based on its index.

locals {
regions = ["us-west-1", "us-east-1", "eu-west-1"]
primary_region = element(local.regions, 1)
}

Here we used element() to designate a specific region as the primary region for my deployment. By using the element() function with an index value of 1, I retrieved the element at index 1 from the regions list, assigning it to primary_region.

Thanks for reading! I’d appreciate your support 👏 and engagement 🚙 in my stories :)

Don’t miss a beat — subscribe to my Medium newsletter to get my latest articles and content before anyone else!

--

--

Ink Insight 🧘🏼
DevOps Dudes

Discover the intersection of DevOps, InfoSec, and mindfulness with Ink Insight. Follow for valuable insights! ✍︎ 👨‍💻 🧘🏼