Types de données HCL, interpolation, références, opérateurs, expressions conditionnelles et boucles.
Types primitifs
# string
variable "env" {
type = string
default = "prod"
}
# number (entier ou décimal)
variable "count" {
type = number
default = 3
}
# bool
variable "enable_https" {
type = bool
default = true
}Types complexes
# list(TYPE) — liste ordonnée, même type
variable "zones" {
type = list(string)
default = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
}
# set(TYPE) — ensemble non ordonné sans doublons
variable "allowed_ips" {
type = set(string)
default = ["10.0.0.1", "10.0.0.2"]
}
# map(TYPE) — dictionnaire clé/valeur, même type de valeur
variable "tags" {
type = map(string)
default = {
Project = "monapp"
Environment = "prod"
}
}
# tuple([TYPE, TYPE, ...]) — liste ordonnée, types hétérogènes
variable "config" {
type = tuple([string, number, bool])
default = ["t3.micro", 2, true]
}
# object({...}) — structure typée
variable "db_config" {
type = object({
host = string
port = number
name = string
ssl = bool
replicas = optional(number, 1) # attribut optionnel avec valeur par défaut
})
}
# any — type dynamique (éviter en prod)
variable "misc" {
type = any
}Interpolation et références
# Interpolation dans une chaîne
name = "server-${var.env}-${count.index}"
tag = "arn:aws:s3:::${var.bucket_name}"
# Heredoc (chaîne multi-ligne)
user_data = <<-EOF
#!/bin/bash
echo "Hello ${var.env}"
apt-get update
apt-get install -y nginx
EOF
# Références aux autres ressources
subnet_id = aws_subnet.private.id
vpc_id = aws_vpc.main.id
depends_on = [aws_internet_gateway.main]
# Référence à un module
db_host = module.database.endpoint
# Référence à une data source
ami_id = data.aws_ami.ubuntu.id
# Référence aux variables et locals
prefix = "${var.project}-${local.env_short}"
# Valeur null
value = nullOpérateurs
# Arithmétique
total = var.base_count + var.extra_count
price = var.unit_price * var.quantity
# Comparaison
is_prod = var.env == "prod"
not_dev = var.env != "dev"
high_count = var.count > 10
at_least_3 = var.count >= 3
# Logiques
enabled = var.enable_feature && var.env == "prod"
either = var.use_s3 || var.use_gcs
negated = !var.disable_feature
# Concaténation de chaînes
full_name = "${var.first}-${var.last}"Expression conditionnelle (ternaire)
CONDITION ? VALEUR_SI_VRAI : VALEUR_SI_FAUX# Taille d'instance selon l'environnement
instance_type = var.env == "prod" ? "t3.large" : "t3.micro"
# Activer ou non le monitoring
monitoring = var.env == "prod" ? true : false
# Valeur par défaut si null
name = var.custom_name != null ? var.custom_name : "default-name"
# Equivalent avec coalesce()
name = coalesce(var.custom_name, "default-name")
# Multi-niveau (éviter si trop complexe → utiliser locals)
size = var.env == "prod" ? "large" : var.env == "staging" ? "medium" : "small"Expression for — transformer des collections
# Transformer une liste
[for ITEM in LIST : EXPRESSION]
[for ITEM in LIST : EXPRESSION if CONDITION]
# Transformer un map
{for KEY, VALUE in MAP : NEW_KEY => NEW_VALUE}
{for KEY, VALUE in MAP : NEW_KEY => NEW_VALUE if CONDITION}# Liste → liste transformée
upper_names = [for name in var.names : upper(name)]
# ["alice", "bob"] → ["ALICE", "BOB"]
# Liste → liste filtrée
prod_servers = [for s in var.servers : s if s.env == "prod"]
# Liste → map (créer un index)
servers_by_id = {for s in var.servers : s.id => s.name}
# Map → liste de valeurs
endpoints = [for k, v in var.services : v.endpoint]
# Map → map transformé
upper_tags = {for k, v in var.tags : k => upper(v)}
# Avec index (count.index équivalent pour for)
indexed = [for i, v in var.names : "${i}: ${v}"]
# Cas d'usage : créer des sous-réseaux
subnets = {
for i, az in var.availability_zones : az => cidrsubnet(var.vpc_cidr, 8, i)
}
# { "eu-west-1a" = "10.0.0.0/24", "eu-west-1b" = "10.0.1.0/24", ... }Opérateur splat [*]
# Extraire un attribut de chaque élément d'une liste de ressources
all_ids = aws_instance.web[*].id
all_ips = aws_instance.web[*].public_ip
# Équivalent for mais plus concis
all_ids = [for instance in aws_instance.web : instance.id]Accès aux éléments
# Liste
first = var.zones[0]
last = var.zones[length(var.zones) - 1]
# Map
region = var.config["region"]
region = var.config.region # notation pointée si clé valide
# Objet imbriqué
port = var.db_config.connection.port
# Accès sécurisé (évite l'erreur si null)
port = try(var.db_config.connection.port, 5432)dynamic — générer des blocs répétés
dynamic "NOM_BLOC" {
for_each = COLLECTION
content {
# attributs du bloc, accès via NOM_BLOC.value
}
}resource "aws_security_group" "web" {
name = "web-sg"
dynamic "ingress" {
for_each = var.allowed_ports
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
# Bloc dynamique avec map
dynamic "tag" {
for_each = local.common_tags
content {
key = tag.key
value = tag.value
}
}En relation avec
- HCL — Vue d’ensemble — hub syntaxe HCL
- Blocs fondamentaux — où ces types sont utilisés
- Meta-arguments — count et for_each utilisent ces expressions
- Fonctions HCL — fonctions sur les types (length, merge, concat…)