DAY #37: [DAY-12] AWS Terraform Functions (Part-2)
Let’s Learn How Built-In Terraform Functions Make Configuration Flexible and Error-Free
![DAY #37: [DAY-12] AWS Terraform Functions (Part-2)](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1764958849359%2F8d4e4dd3-d3e2-415c-9a7d-2beb182d495d.png&w=3840&q=75)
Introduction
Hello and welcome back, it’s good to see you here again.
We’re now on Day 12 of our 30-day AWS Terraform journey, and it really does feel like we’re continuing a conversation we paused only yesterday. That steady, day-by-day progress is what makes this whole thing manageable and, honestly, kind of enjoyable.
If you remember, on Day 11 we opened the door to Terraform functions: we saw what they are, ran a few demos, and began to get a feel for how Terraform “thinks.” That day was about getting comfortable with the ideas and seeing how small functions fit into a larger workflow. Today we pick up right where we left off, carrying the same slow, steady pace.
So settle in, make yourself comfortable, and let’s explore this next chapter together.

Personal tidbit time:
Fact #12: I’m not a big fan of mathematics, as a kid I used to dread it. And I think a big part of that was because I never really tried to understand it. Looking back, I actually feel a little sad for my younger self, if only I could explain things to that version of me in a simpler way, maybe it wouldn’t have felt so overwhelming.
Understanding Validation Functions
Before we jump into the Terraform code, let’s take a moment to understand why validation functions matter.
Imagine we’re asking someone to fill out a small form maybe choosing an instance type or providing a backup name. Now, people make mistakes. They might type something too short, too long, or in a completely different format. If Terraform went ahead without checking anything, we’d only discover the mistake much later, often after the infrastructure has already been created incorrectly.
That’s where validation functions step in.
And the best part? These validations happen before Terraform even starts planning anything.
Why validation goes inside the variable block
Unlike other checks we’ve done before, validation has to live inside the variable declaration itself.
That’s because we’re telling Terraform:
“Whenever someone provides a value for this variable, please check these rules first.”
Here’s the example:

Let’s break this down.
1. First validation: checking the length
Terraform first checks whether the instance type is at least 2 characters long and at most 20.
Why?
Because sometimes someone may type something extremely short like t or something very long accidentally. This rule keeps things sensible.
The validation says:
if the length is 2–20, we’re good
if not, Terraform stops you with the message:
“instance type must be between 2 and 20 characters”
Simple and helpful.
2. Second validation: checking if it starts with t2 or t3
This one is more interesting.
Here’s the condition again:

Let’s break it into very easy language:
regex()
→ checks whether a value matches a specific patternthe pattern
^t[2-3]\.means:
“The value should start with t2. or t3.”can()
→ used so Terraform can safely test the regex without crashing
Think of the regex like a rulebook:
^= start of the stringt= must start with the letter "t"[2-3]= followed by either 2 or 3\.= then there must be a dot (.)
So valid examples are:
t2.micro
t2.small
t3.large
Invalid ones would be:
m5.large
t4.micro
t2micro (missing dot)
And if the input doesn’t follow the pattern, Terraform returns our custom error:
“Instance type must start with T2 or T3.”
This makes the error more human-friendly and less confusing.
Why can() is needed
If we used only regex(), Terraform might throw a harsh technical error if the pattern didn’t match.
But with can(), Terraform simply checks:
If regex works → return true
If regex fails → return false, but gracefully (no crashes)
An example to relate
Imagine we're checking someone’s ID:
First, check if the ID length is reasonable (not too short, not too long).
Then check if it starts with a certain prefix like "AB" or "BC".
If both checks pass, great, let them in.
If not, we politely say, “Sorry, this ID doesn’t look right.”
Terraform is doing exactly that for our variables.
A Practical Validation: Ensuring a Backup Name Ends With -backup
Now that we understand how validations work with instance_type, let’s look at another everyday example, something even simpler.
Imagine we’re creating a variable called backup name.
We want every backup to follow a proper naming pattern so it’s easy to identify later.
Let’s say the rule is:
“Every backup name must end with
-backup.”
Why is this useful?
Because when our systems grow, naming patterns save us from chaos.
Backups become easy to filter, group, search, and automate around, all because they follow a familiar ending.
The Terraform validation
Here’s how it might look:

Let’s unpack this.
1. endswith() function
endswith(string, substring) simply checks whether a value ends with a specific text.
So:
"mydata-backup"→ valid ✔"backup-mydata"→ invalid ❌"mydata-backup123"→ invalid ❌
Terraform evaluates the condition, and if it fails, it shows you the custom message we provided.
We can enforce structure before Terraform even plans anything.
Understanding Sensitive Variables (Why Some Values Stay Hidden)
Some Terraform variables hold harmless information, like names or flags.
But others may contain things that should never appear in logs or screens i.e. things like passwords, tokens, keys, or database connection strings.
Terraform gives us a simple way to protect such values:
Mark the variable as
sensitive = true.
This doesn’t encrypt the value, but it does hide it from output, logs, and accidental exposure during terraform plan or terraform apply.
Terraform example

Now, even if someone tries to print it:

Terraform will hide it.
You’ll see something like:

Why this matters
Sensitive variables protect us from:
accidental screen-sharing leaks
logs exposing secrets
commit mistakes when values accidentally get echoed
teammates seeing secrets they don’t need to
It’s not encryption, but it’s a safety layer that prevents embarrassment and accidents.
Validations Using Regex
So far, our validations checked simple conditions like:
Does this value belong to a list?
Does this value end with “-backup”?
But sometimes we need more powerful rules, rules that check patterns, formats, or structures.
This is where regex (regular expressions) comes in.
Regex sounds scary, but in Terraform, we’ll mostly use it for simple checks like:
Does the value contain only letters and numbers?
Does the name follow a specific pattern?
Does it start with something specific?
Does it avoid special characters?
A simple explanation of regex
Think of regex as a pattern detective.
Instead of checking a single condition, it looks for a shape in the text.
Example in plain English:
“The name must start with a letter and can only contain letters, numbers, and hyphens.”
Regex lets Terraform enforce that in one line.
Terraform regex example
Let’s say we want our environment names to follow this rule:
“Must start with a letter, and can contain letters, numbers, and hyphens.”
The regex for that (very common pattern) is:

We’ll understand what the above gibbersh means in a while.
Here’s how we apply it in Terraform:

Breaking this down in simple terms
1. ^ and $
These mean “start” and “end”.
Terraform checks the whole string, not just a part.
2. [a-zA-Z]
The name must start with a letter.
3. [a-zA-Z0-9-]*
After the first letter, we can have:
letters
numbers
hyphens
repeated any number of times (
*)
Why regex matters in Terraform
When our project grows, naming mistakes create chaos:
S3 buckets with weird characters
IAM roles with spaces
Environment names with typos
Random uppercase/lowercase mixtures
Regex is our gatekeeper.
It stops wrong values before they spread through our infrastructure.
If this section is good, we’ll move to the next one:
Validation Rules for Lists
So far, we’ve seen validations for single values: an instance type, a backup name, or an environment name.
But what if our variable is a list of values? For example, a list of regions, instance types, or users.
Terraform lets us apply validations to every item in the list, ensuring consistency across the board.
Why this matters
Imagine we have a list of regions:

We want all regions to:
Follow the proper format
Only contain letters, numbers, and hyphens
Avoid typos or accidental spaces
Without validation, Terraform would happily accept a wrong entry, and our deployments could fail later.
With validations, Terraform stops mistakes upfront.
Terraform example
Suppose we have a variable for allowed regions:

Breaking it down
for r in var.allowed_regions
Iterates over every region in the list.regex("^[a-z]{2}-[a-z]+-[0-9]$", r)
Ensures each region follows AWS naming conventions i.e.Accepted values:
us-east-1Rejected values:
USEAST1,us-east
can()
Handles errors gracefully if the regex fails.alltrue([...])
Ensures that every single item passes the condition. If even one fails, Terraform stops and shows our custom error.
Why list validation is useful
Prevents subtle mistakes across multiple entries
Makes infrastructure predictable
Saves time debugging deployment errors
Ensures human-friendly, consistent standards
Type Conversion Functions (Lists, Sets, and Unique Values)
In Terraform, sometimes we need to change the type of a variable to make it easier to work with.
This is especially common when dealing with lists and sets, or when we want to remove duplicate values.
Why this matters
Imagine we have a list of regions:

Notice how “us-east-1” appears twice.
A list allows duplicates
A set only keeps unique values
Converting a list to a set is a simple way to automatically remove duplicates, making our infrastructure cleaner and more predictable.
Terraform example: Converting a list to a set
Suppose we have two variables:

We can combine them with concat:

This produces:

Now, to get only unique locations, use toset:

Result:

Duplicates are automatically removed, no extra effort needed.
Why type conversion is useful
Cleans up data automatically
Makes further operations easier
Prevents mistakes when working with lists that shouldn’t have duplicates
Bridges differences between Terraform’s list and set types
Number Functions: Sum, Max, Min, Absolute, and Average
Terraform provides several handy number functions that help us perform calculations on variables, especially lists of numbers.'
These functions are useful for things like monthly costs, resource counts, or any scenario where we need math on our infrastructure data.
The scenario
Suppose we have a list of monthly costs (some are credits, so negative):

We want to:
Convert everything to positive numbers
Find the maximum cost
Find the minimum cost
Calculate the total cost
Calculate the average cost
Step 1: Convert to positive values
Terraform’s abs() function returns the absolute value of a number.
But because abs() doesn’t work on a list directly, we use a for loop:

Result:

Step 2: Find max and min
Terraform provides max() and min() functions.
Apply them on our positive list:

Result:

Step 3: Calculate total and average
To sum all costs:

Result:

Average is simply total divided by the number of elements:

Result:

Why this matters
Handles negative/credit values easily
Calculates statistics across any list of numbers
Helps in budgeting, reporting, or monitoring infrastructure costs
Makes our Terraform configurations smarter and more automated
Timestamp Functions: Current Time and Formatting
Terraform also provides timestamp functions to help us capture and format the current time.
This can be useful for logging, backups, or creating time-stamped resources automatically.
An example
Terraform’s timestamp() function doesn’t need any input:

This produces a value like:

This is the current UTC timestamp in ISO 8601 format.
Formatting the timestamp
Sometimes, we may want a more human-friendly format.
Terraform provides formatdate():

Result:

Now we can use this formatted timestamp in backup names, logs, or resource tags.
Why timestamp functions matter
Helps with automation that relies on dates
Makes logs and outputs easier to interpret
Supports versioning and auditing in our Terraform deployments
File Handling Functions
Terraform provides file handling functions that let us read, decode, and use data from files directly in our configurations.
This is especially useful when working with JSON configuration files or other structured data.
The scenario
Suppose we have a JSON file config.json:

We want Terraform to:
Check if the file exists
Read its contents
Decode the JSON into a usable map
Terraform example

Breaking it down
fileexists("config.json")
Checks if the file exists. Returnstrueorfalse.file("config.json")
Reads the contents of the file.jsondecode(...)
Converts the JSON text into a Terraform map or object.Conditional operator (
? :)
If the file exists → decode it
If not → return an empty map{}
Output example

Now Terraform can use the database host, API endpoint, or any other value from the JSON file in our infrastructure resources.
Additional notes
Terraform also provides jsonencode() to convert data structures back into JSON
File handling functions let us reuse external data safely and efficiently
Great for keeping secrets, configurations, or templates outside our main
.tffiles
Why this matters
Makes our Terraform configurations more dynamic and flexible
Keeps sensitive or large configuration data outside our main code
Supports automation, templating, and scaling your deployments
Conclusion
And with this, we’ve reached the end of Day 12 in our 30-day Terraform journey.
Today we closed the loop on the remaining Terraform functions, everything we couldn’t finish in Part 1 finally found its place here in Part 2.
We explored validations, sensitive values, type conversions, numeric functions, timestamps, and even dipped our toes into file handling.
Each of these shape the kind of Terraform code that behaves reliably, predictably, and in a way that protects us from surprises.
And I just want to say this: if you’ve been following along till Day 12, that’s not a small thing.
Learning something every day, especially something as deep and layered as Terraform, is not easy.
We’ve come this far, and there’s still a long, exciting road ahead. We’ll tackle it together!
And hey, if you still have doubts or something felt a bit fuzzy, here’s a helpful video by Piyush Sachdeva that might clear things up.
Never hesitate to revisit, rewatch, or relearn.
With that thought, I’ll leave you for today. We’ll catch up again tomorrow with a new topic tomorrow.
Peace!



![Day #47: [DAY-22] Two Tier Architecture Setup on AWS Using Terraform](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1766423595267%2F6582f7e7-0485-445b-9117-36f5abbe5d44.png&w=3840&q=75)