Terraform fournit un ensemble de fonctions built-in utilisables dans les expressions. Elles ne peuvent pas être définies par l’utilisateur (utiliser locals à la place).

Tester dans terraform console : echo 'upper("hello")' | terraform console


Fonctions de chaîne

# Casse
upper("hello")             # "HELLO"
lower("HELLO")             # "hello"
title("hello world")       # "Hello World"
 
# Longueur
length("hello")            # 5
 
# Manipulation
trimspace("  hello  ")     # "hello"
trim("xxhelloxx", "x")     # "hello"
trimprefix("hello-world", "hello-")   # "world"
trimsuffix("hello-world", "-world")   # "hello"
 
# Recherche et remplacement
replace("hello world", " ", "_")      # "hello_world"
replace("a-b-c", "/[a-c]/", "x")      # "x-x-x" (regex)
startswith("hello", "he")             # true
endswith("hello", "lo")               # true
strcontains("hello world", "world")   # true
substr("hello world", 6, 5)           # "world"
 
# Séparation et assemblage
split(",", "a,b,c")           # ["a", "b", "c"]
join("-", ["a", "b", "c"])    # "a-b-c"
join(", ", var.names)         # "Alice, Bob, Charlie"
 
# Formatage
format("Hello, %s! Port: %d", "World", 8080)  # "Hello, World! Port: 8080"
format("%04d", 5)             # "0005"
format("%.2f", 3.14159)       # "3.14"
formatlist("server-%02d", [1,2,3])  # ["server-01", "server-02", "server-03"]
 
# Padding
indent(2, "line1\nline2")     # "line1\n  line2" (utile dans heredoc)

Fonctions de collection

# Longueur
length([1, 2, 3])             # 3
length({a=1, b=2})            # 2
 
# Accès et recherche
element([1, 2, 3], 1)         # 2 (index, boucle si dépassement)
index(["a","b","c"], "b")     # 1
contains(["a","b","c"], "b")  # true
keys({a=1, b=2})              # ["a", "b"]
values({a=1, b=2})            # [1, 2]
lookup({a=1, b=2}, "c", 0)    # 0 (valeur par défaut si absent)
lookup(var.config, var.key)   # valeur ou erreur si absent
 
# Fusion et transformation
concat(["a","b"], ["c","d"])  # ["a","b","c","d"]
flatten([[1,2],[3,[4,5]]])     # [1,2,3,4,5]
merge({a=1}, {b=2}, {c=3})    # {a=1, b=2, c=3}
merge(var.default_tags, var.extra_tags)  # merge de maps
 
# Sélection
slice([1,2,3,4,5], 1, 3)      # [2, 3] (de l'index 1 inclus à 3 exclus)
one(["unique"])               # "unique" (erreur si != 1 élément)
 
# Conversion
tolist(toset([1,2,2,3]))      # [1,2,3] (dédupliqué, ordre non garanti)
toset(["a","b","a"])          # toset(["a", "b"])
tomap({a="1", b="2"})         # converti en map
tonumber("42")                # 42
tostring(42)                  # "42"
tobool("true")                # true
 
# Tri
sort(["c","a","b"])           # ["a","b","c"]
reverse([1,2,3])              # [3,2,1]
 
# Mathématiques sur collections
sum([1,2,3,4])                # 10
min(3, 1, 4, 1, 5)            # 1
max(3, 1, 4, 1, 5)            # 5

Fonctions numériques

abs(-5)           # 5
ceil(1.2)         # 2
floor(1.9)        # 1
round(1.5)        # 2
min(3, 1, 5)      # 1
max(3, 1, 5)      # 5
pow(2, 10)        # 1024
signum(-5)        # -1
log(8, 2)         # 3.0  (log base 2 de 8)
parseint("FF", 16)  # 255  (hexadécimal → décimal)

Fonctions d’encodage

# Base64
base64encode("Hello, World!")      # "SGVsbG8sIFdvcmxkIQ=="
base64decode("SGVsbG8sIFdvcmxkIQ==")  # "Hello, World!"
base64gzip(data.template_file.script.rendered)
 
# JSON
jsonencode({key = "value", list = [1,2,3]})
# → "{\"key\":\"value\",\"list\":[1,2,3]}"
 
jsondecode("{\"key\":\"value\"}")
# → {key = "value"}
 
# YAML (lecture seulement)
yamldecode(file("config.yaml"))
 
# URL
urlencode("hello world/path?q=1")  # "hello+world%2Fpath%3Fq%3D1"

Fonctions de hash

md5("hello")                          # "5d41402abc4b2a76b9719d911017c592"
sha1("hello")                         # "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d"
sha256("hello")                       # "2cf24dba5fb0..."
sha512("hello")                       # "..."
 
# Hash d'un fichier (utile pour détecter les changements)
filemd5("script.sh")
filesha256("script.sh")               # ← changer le hash → Terraform recrée la ressource
 
# Bcrypt (pour mots de passe)
bcrypt("motdepasse", 10)
 
# UUID
uuid()                                # "b5ee72a3-54dd-c4b8-551c-4bdc0204cedb"
uuidv5("dns", "exemple.com")         # UUID déterministe

Fonctions réseau et IP

# Décomposer un CIDR
cidrhost("10.0.0.0/24", 5)         # "10.0.0.5"    (Nième hôte du réseau)
cidrnetmask("10.0.0.0/24")         # "255.255.255.0"
cidrsubnet("10.0.0.0/16", 8, 0)    # "10.0.0.0/24"  (sous-réseau)
cidrsubnet("10.0.0.0/16", 8, 1)    # "10.0.1.0/24"
cidrsubnets("10.0.0.0/16", 8, 8, 8)  # ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
cidrcontains("10.0.0.0/24", "10.0.0.5")  # true
 
# Cas d'usage : générer des subnets dynamiquement
locals {
  azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  public_subnets  = [for i, _ in local.azs : cidrsubnet(var.vpc_cidr, 8, i)]
  private_subnets = [for i, _ in local.azs : cidrsubnet(var.vpc_cidr, 8, i + 10)]
}

Fonctions de fichier

# Lire le contenu d'un fichier
file("./scripts/user_data.sh")
file("${path.module}/templates/config.tpl")
 
# Template (remplace les variables ${...})
templatefile("./templates/user_data.tpl", {
  db_host = aws_db_instance.main.endpoint
  env     = var.env
})
 
# Hash d'un fichier
filemd5("./scripts/startup.sh")     # détecter les changements
 
# Chemin vers le module courant
path.module    # répertoire du fichier .tf courant
path.root      # répertoire racine de la configuration
path.cwd       # répertoire de travail courant

Fonctions de date et heure

timestamp()                    # "2026-04-05T14:30:00Z" (ISO 8601, UTC)
timeadd(timestamp(), "24h")    # +24 heures
timecmp("2026-01-01T00:00:00Z", "2026-06-01T00:00:00Z")  # -1
 
# Formatter une date
formatdate("DD MMM YYYY", timestamp())   # "05 Apr 2026"
formatdate("YYYYMMDDhhmmss", timestamp()) # "20260405143000"

Fonctions de type et validation

# Vérifier le type
can(tonumber("abc"))       # false (essai de conversion sans erreur)
try(tonumber(var.x), 0)    # 0 si la conversion échoue
 
# Coalesce : première valeur non-null
coalesce(null, null, "valeur")         # "valeur"
coalesce(var.name, "default-name")
 
# Coalesce pour listes
coalescelist([], [], ["a", "b"])       # ["a", "b"]
 
# Validation de type
type(42)       # "number"
type("hello")  # "string"
type([])       # "tuple"

En relation avec