π― Goal: Move from expressions β functions β reusable, built-in logic for safe, DRY configs.
β Youβll master:
- β String:
lower(),replace(),substr(),trim()- β Numeric:
max(),min(),abs()- β Collection:
length(),concat(),merge()- β Type Conversion:
toset(),tonumber(),tostring()- β Lookup:
lookup()for env-specific configs- β
forexpressions (notfor_each!) for list/map transforms
β Without functions:
- Manual S3 bucket name cleanup β
bucket = "Project Alpha!!!"β apply fails- Copy-paste
tags = { Env = "dev", Cost = "eng" }across 20 resources- Hardcoded
instance_type = "t3.medium"in prod
β With functions:
β Infrastructure that self-corrects invalid inputs
β Truly DRY configs (no repeated logic)
β Environment-aware resources (dev/staging/prod)
π‘ Key Insight:
Terraform has 100+ built-in functions β but no custom functions.
β Use them like LEGO blocks β small, composable, powerful.
| Category | Key Functions | Use Case |
|---|---|---|
| String | lower(), replace(), substr(), trim() |
Sanitize names, tags, IDs |
| Numeric | max(), min(), abs() |
Cost tracking, capacity planning |
| Collection | length(), concat(), merge() |
Combine lists/maps |
| Type Conversion | toset(), tonumber(), tostring() |
Normalize inputs, dedupe |
| Lookup | lookup(map, key, default) |
Env-specific configs |
π― Golden Rule:
βChain functions like shell pipes:
lower(replace(...))β clean, readable, safe.β
variables.tf)variable "project_name" {
type = string
default = "Project Alpha Resource!!"
}
variable "bucket_name_raw" {
type = string
default = "Project Alpha Storage!! 123"
}
variable "allowed_ports_str" {
type = string
default = "80,443,8080,3306"
}
variable "instance_sizes" {
type = map(string)
default = {
dev = "t2.micro"
staging = "t3.small"
prod = "t3.large"
}
}
variable "default_tags" {
type = map(string)
default = {
ManagedBy = "Terraform"
Company = "TechCorp"
}
}
variable "env_tags" {
type = map(string)
default = {
Environment = "dev"
CostCenter = "engineering"
}
}