interview-prep

Crisp answer: Terraform has ~100 built-in functions for string manipulation, numeric operations, collection handling, encoding, and filesystem operations. You cannot define your own functions — use locals to compose expressions.

String functions:

lower("HELLO-WORLD")        # "hello-world"
upper("hello")              # "HELLO"
replace("hello world", " ", "-")  # "hello-world"
trimspace("  hello  ")      # "hello"
split(",", "a,b,c")         # ["a", "b", "c"]
join("-", ["web", "prod"])  # "web-prod"
format("%-10s %d", "web", 3)  # "web        3"

# String templating functions
substr("hello world", 0, 5)  # "hello"
length("hello")              # 5

# Check and manipulate
startswith("web-prod", "web")  # true
endswith("web-prod", "prod")   # true
contains(["a","b","c"], "b")   # true

Collection functions:

length(["a", "b", "c"])     # 3
length({a = 1, b = 2})      # 2

flatten([["a", "b"], ["c"]])  # ["a", "b", "c"]

distinct(["a", "b", "a", "c"])  # ["a", "b", "c"]

keys({a = 1, b = 2})         # ["a", "b"]
values({a = 1, b = 2})       # [1, 2]

merge({a = 1}, {b = 2})      # {a = 1, b = 2}
merge(local.common_tags, {Name = "web"})  # merge tags

lookup(var.ami_map, var.region, "ami-default")  # get with default
toset(["a", "b", "a"])       # {"a", "b"}  (dedup)
tolist(toset(["b", "a"]))    # ["a", "b"]  (sorted)

Numeric functions:

max(3, 1, 4, 1, 5)           # 5
min(3, 1, 4)                  # 1
abs(-5)                       # 5
ceil(1.2)                     # 2
floor(1.8)                    # 1

IP/CIDR functions:

# Divide a VPC CIDR into subnets:
cidrsubnet("10.0.0.0/16", 8, 0)  # "10.0.0.0/24" (add 8 bits, subnet 0)
cidrsubnet("10.0.0.0/16", 8, 1)  # "10.0.1.0/24" (add 8 bits, subnet 1)
cidrsubnet("10.0.0.0/16", 8, 2)  # "10.0.2.0/24"

# Extract subnet size:
cidrnetmask("10.0.0.0/24")   # "255.255.255.0"
cidrhost("10.0.0.0/24", 5)   # "10.0.0.5"

Encoding functions:

base64encode("hello world")   # "aGVsbG8gd29ybGQ="
base64decode("aGVsbG8gd29ybGQ=")  # "hello world"
jsonencode({key = "value"})   # "{\"key\":\"value\"}"
jsondecode("{\"key\":\"value\"}")  # {key = "value"}
yamlencode({key = "value"})   # "key: value\n"

File functions:

file("scripts/bootstrap.sh")          # Read file contents as string
filebase64("certs/ca.crt")            # Read file as base64
templatefile("templates/policy.json.tpl", {
  bucket = aws_s3_bucket.main.id
  region = var.region
})                                     # Render a template file with variables

What to say in the interview:

"The functions I reach for most: cidrsubnet for calculating subnet CIDRs from a VPC block, merge for combining common_tags with resource-specific tags, jsonencode for IAM policies inline in Terraform rather than template files, and flatten when I end up with a list of lists that I need to flatten for for_each. The cidrsubnet pattern is particularly useful for generating subnets from a variable VPC CIDR without having to hardcode every subnet CIDR."


My notes