🎯 Goal: Add safety rails to your configs — validate inputs, handle time, read files, and crunch numbers safely.
✅ You’ll master:
- ✅ Validation:
length(),regex(),can(),endswith()- ✅ Numeric:
sum(...),max(...),abs()+ spread operator...- ✅ Time:
timestamp(),formatdate()for audit trails- ✅ File:
fileexists(),file(),jsondecode()for external configs
variables.tf — Safe Instance Typesvariable "instance_type" {
description = "EC2 instance type (T2/T3 only)"
type = string
default = "t3.micro"
validation {
# 🔹 Rule 1: Length 2–20 chars
condition = (
length(var.instance_type) >= 2 &&
length(var.instance_type) <= 20
)
error_message = "Instance type must be 2–20 characters."
}
validation {
# 🔹 Rule 2: Must match t2./t3. (e.g., t3.micro)
condition = can(regex("^t[23]\\\\\\\\.\\\\\\\\w+$", var.instance_type))
error_message = "Instance type must be t2.* or t3.* (e.g., t3.micro)."
}
}
✅ How can(regex(...)) works:
regex() alone → crashes on no-matchcan(regex()) → returns true/false → safe for validation💡 Pro Tip:
Use
can()with any error-prone function:can(cidrhost(...)),can(jsondecode(...)).
endswith() & sensitive# Enforce backup naming: "db-prod-backup"
variable "backup_name" {
type = string
validation {
condition = endswith(var.backup_name, "-backup")
error_message = "Backup name must end with '-backup'."
}
}
# Hide secrets in logs/state
variable "api_key" {
type = string
sensitive = true # 🔒 Masks in `plan`/`output`
# ⚠️ Still base64-encoded in state — use Vault/SSM for true secrets!
}
variable "monthly_costs" {
type = list(number)
default = [200, -50, 300, 75] # Negative = credit
}
for + abs() + sum(...)(Yes — the spread operator ... is critical!)
locals {
# 🔹 Convert all to positive (abs per element)
positive_costs = [for c in var.monthly_costs : abs(c)]
# → [200, 50, 300, 75]
# 🔹 Use `...` to unpack list → args for sum/max/min
total_cost = sum(local.positive_costs...) # → 625
max_cost = max(local.positive_costs...) # → 300
min_cost = min(local.positive_costs...) # → 50
avg_cost = local.total_cost / length(local.positive_costs) # → 156.25
}