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) # 5Fonctions 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éterministeFonctions 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 courantFonctions 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
- HCL — Vue d’ensemble — hub syntaxe HCL
- Types et expressions — types auxquels ces fonctions s’appliquent
- terraform console — tester les fonctions en interactif