Day 11 - Terraform Functions Part 1

Today I worked on Day 11 of my AWS Terraform learning journey. The focus was Terraform built-in functions and how they help clean, transform, validate, and reuse values inside infrastructure code.

Terraform functions are small but powerful helpers. They are not custom functions like in Python or JavaScript. Instead, they are built into Terraform and can be used inside expressions to produce better names, cleaner tags, validated inputs, dynamic lists, and reusable configurations.

For this day, I focused on six practical assignments.

What I Built

In this hands-on lab, I created:

A VPC with merged tags
An S3 bucket with a cleaned and formatted bucket name
A security group with ports generated from a comma-separated variable
An EC2 instance with instance type selected by environment
Input validation for instance type format
Outputs to clearly show how each function transformed the values

Functions Covered

lower()

The lower() function converts text into lowercase.

I used it to convert a raw project name into a cleaner naming format.

Example:

lower("Project ALPHA Resource")

Result:

project alpha resource

This is useful because AWS resource names often need consistent lowercase naming.

Terraform console showing lower function output


replace()

The replace() function replaces part of a string with another value.

I used it to replace spaces with hyphens.

Example:

replace(lower(var.project_name), " ", "-")

This changed:

Project ALPHA Resource

Into:

project-alpha-resource

This is a simple but important step for building clean resource names.

Terraform output showing formatted project name


merge()

The merge() function combines multiple maps into one map.

I used it to combine default tags and environment-specific tags.

Example:

merge(local.default_tags, local.environment_tags)

This helped me build one common tag block that can be reused across resources.

Instead of repeating tags in every resource, I created them once in locals and reused them.

Terraform plan showing tags on VPC, S3 bucket, security group, and EC2


substr()

The substr() function extracts part of a string.

I used it to limit the S3 bucket name length.

Example:

substr(local.cleaned_bucket_name, 0, 50)

This is useful because AWS services have naming limits, and Terraform functions can help enforce naming rules before resources are created.

Terraform output showing final cleaned bucket name



split(), join(), and for Expression

The split() function turns a string into a list.

Example:

split(",", "80,443,8080")

Result:

["80", "443", "8080"]

I used this to take a comma-separated list of ports and turn it into security group rules.

Then I used a for expression with tonumber() to convert the values into numbers.

[for port in local.allowed_ports_list : tonumber(port)]

Finally, I used join() to convert the list back into readable text for output.

This helped me understand how Terraform can take simple input and convert it into dynamic infrastructure logic.

Terraform plan showing security group ingress rules for 80, 443, and 8080


lookup()

The lookup() function gets a value from a map.

I used it to select the EC2 instance type based on the environment.

Example:

lookup(var.instance_type_by_environment, var.environment, "t3.micro")

For my dev environment, Terraform selected:

t3.micro

This is useful because the same code can behave differently across dev, qa, and prod environments.

Terraform output showing selected instance type


length(), can(), and regex()

These functions were used for validation.

The length() function checks how long a value is.
The regex() function checks whether a value matches a pattern.
The can() function safely tests whether an expression works without breaking the configuration.

I used them together to validate the EC2 instance type.

length(var.selected_instance_type) > 0 && can(regex("^[a-z][0-9][a-z]?\\.[a-z]+$", var.selected_instance_type))

This makes sure the instance type looks like a valid AWS instance type such as:

t3.micro
m5.large

This was one of the most useful parts of the day because validation helps catch bad input early.

terraform validate success


Optional test with invalid instance type showing validation error


What I Tested

I tested the functions in two ways.

First, I used terraform console to test individual functions before using them in code.

Second, I ran the full Terraform workflow:

terraform init
terraform fmt
terraform validate
terraform plan
terraform apply -auto-approve
terraform output
terraform destroy -auto-approve

The console was very helpful because it allowed me to test function behavior quickly without creating resources.

Terraform console with lower, replace, split, join, lookup, and regex tests


Final Result

By the end of Day 11, I had a working Terraform configuration that used functions to create cleaner names, reusable tags, dynamic security group rules, environment-based instance selection, and input validation.

The biggest lesson from today was simple:

Terraform functions make infrastructure code smarter without making it complicated.

They help turn raw input into clean, reliable, reusable configuration. Small functions, big impact.

Video Reference


Jay

Comments

Popular posts from this blog

ASM Integrity check failed with PRCT-1225 and PRCT-1011 errors while creating database using DBCA on Exadata 3 node RAC

Lock Tables in MariaDB

Life is beautiful