Aller au contenu principal
TerraformInfrastructure as CodeFormation

Variables et types de données

30 min de lecture Terraform — Chapitre 3

Maîtrise les variables d'entrée Terraform, les différents types (string, number, list, map, object), l'assignation de valeurs et les outputs.

Jusqu’ici, toutes les valeurs étaient en dur dans le code. Ça fonctionne pour un lab, mais en entreprise tu as des environnements dev, staging, prod — tous avec des configs différentes. Les variables transforment ton code Terraform en template réutilisable. C’est ce qui sépare un prototype d’une vraie infrastructure.

Déclarer des variables d’entrée

Une variable d’entrée injecte une valeur dans ta configuration sans modifier le code. Tu la déclares avec le bloc variable et tu la références avec var.nom.

variable "server_name" {
  description = "Nom du serveur à créer"
  type        = string
  default     = "web-1"
}

variable "server_count" {
  description = "Nombre de serveurs"
  type        = number
  default     = 1
}

variable "enable_backups" {
  description = "Activer les backups automatiques"
  type        = bool
  default     = false
}

Trois arguments essentiels : description (obligatoire moralement), type (détecte les erreurs tôt) et default (rend la variable optionnelle).

💡 Règle : si une variable n’a pas de default, Terraform la demandera interactivement au plan/apply. En CI/CD, ça bloque le pipeline. Définis toujours un default ou fournis la valeur explicitement.

Types complexes

HCL va bien au-delà des scalaires. Les types complexes te permettent de structurer tes données proprement :

# Liste — collection ordonnée d'un même type
variable "allowed_ports" {
  type    = list(number)
  default = [22, 80, 443]
}

# Map — paires clé-valeur
variable "tags" {
  type = map(string)
  default = {
    Environment = "dev"
    Team        = "platform"
  }
}

# Object — structure typée avec des champs nommés
variable "database" {
  type = object({
    engine   = string
    size     = number
    multi_az = bool
  })
  default = {
    engine   = "postgres"
    size     = 50
    multi_az = false
  }
}

La différence clé : map a des clés dynamiques du même type, object a des champs fixes avec des types différents. Utilise object quand la structure est connue à l’avance, map quand les clés varient.

Validation des valeurs

Depuis Terraform 0.13, tu peux valider les variables en amont — le plan échoue immédiatement avec un message clair au lieu de planter à mi-chemin :

variable "environment" {
  type        = string
  description = "Environnement cible"

  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "L'environnement doit être dev, staging ou prod."
  }
}

variable "server_count" {
  type = number
  validation {
    condition     = var.server_count > 0 && var.server_count <= 20
    error_message = "Le nombre de serveurs doit être entre 1 et 20."
  }
}

🔥 En entreprise, c’est indispensable. Sans validation, un server_count = 500 passe au plan et crée 500 serveurs avant que quelqu’un ne s’en rende compte.

Variables sensibles

Pour les secrets, marque la variable comme sensitive — Terraform masque la valeur dans les logs et le plan :

variable "db_password" {
  type      = string
  sensitive = true
}

⚠️ Attention : sensitive masque l’affichage, mais ne chiffre rien dans le state. Pour protéger le state, utilise un backend distant chiffré (S3 avec KMS, Terraform Cloud).

Assigner des valeurs aux variables

Plusieurs méthodes, par ordre de priorité croissante (la dernière gagne) :

  1. default dans la déclaration
  2. terraform.tfvars — chargé automatiquement
  3. *.auto.tfvars — chargé automatiquement (ordre alphabétique)
  4. -var-file="prod.tfvars" — fichier explicite
  5. -var="region=eu-west-1" — en ligne de commande
  6. TF_VAR_region=eu-west-1 — variable d’environnement

La convention la plus courante : un fichier .tfvars par environnement.

# prod.tfvars — puis : terraform apply -var-file="prod.tfvars"
environment    = "prod"
server_count   = 3
server_name    = "api-prod"
enable_backups = true

tags = {
  Environment = "production"
  CostCenter  = "engineering"
}

⚠️ Ne commite jamais un .tfvars contenant des secrets. Utilise des variables d’environnement (TF_VAR_db_password) ou un gestionnaire de secrets (Vault, AWS Secrets Manager).

Les outputs : exposer des valeurs

Les outputs affichent des informations après apply et permettent de partager des données entre modules.

output "server_ip" {
  description = "IP publique du serveur"
  value       = hcloud_server.web.ipv4_address
}

output "server_url" {
  description = "URL d'accès au serveur"
  value       = "https://${hcloud_server.web.ipv4_address}"
}

output "db_endpoint" {
  description = "Endpoint de la base"
  value       = hcloud_server.db.ipv4_address
  sensitive   = true
}

Après apply, Terraform affiche les outputs non sensibles. Tu peux les requêter avec terraform output ou terraform output -raw server_ip pour le scripting. Dans un contexte multi-modules, les outputs d’un module enfant sont accessibles via module.nom_module.nom_output.

Les locals : variables internes calculées

Les locals sont des valeurs calculées en interne — des alias que personne ne peut surcharger de l’extérieur. Parfait pour éviter la répétition et clarifier le code.

locals {
  name_prefix = "${var.project}-${var.environment}"
  is_prod     = var.environment == "prod"

  common_tags = {
    Project     = var.project
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

resource "hcloud_server" "web" {
  name        = "${local.name_prefix}-web"
  server_type = local.is_prod ? "cx32" : "cx22"
  image       = "ubuntu-24.04"

  labels = local.common_tags
}

Quand utiliser quoi ?

  • variable = paramètre d’entrée fourni par l’appelant (configurable)
  • locals = valeur dérivée, calculée en interne (non configurable)
  • output = valeur de sortie, exposée à l’extérieur

💡 Règle pratique : si tu écris la même expression plus de deux fois, crée un local. Si la valeur doit être paramétrable, c’est une variable.

Cas entreprise : multi-environnements avec les mêmes fichiers

Une équipe gère 3 environnements (dev, staging, prod) pour une application SaaS. Sans variables, ils avaient 3 dossiers avec du code quasi-identique — un cauchemar de maintenance.

Avec les variables, un seul jeu de fichiers .tf et 3 fichiers .tfvars :

infra/
├── main.tf
├── variables.tf
├── outputs.tf
├── dev.tfvars      # 1 serveur cx22, pas de backup
├── staging.tfvars  # 2 serveurs cx22, backup activé
└── prod.tfvars     # 3 serveurs cx32, backup + monitoring

Le code est identique, seules les valeurs changent. Un changement d’architecture se fait une seule fois et se propage automatiquement. Les code reviews sont plus simples — on revoit du code, pas des valeurs.

🎯 Le gain : quand ils ajoutent un 4e environnement (sandbox), c’est un nouveau fichier .tfvars de 10 lignes. Pas 500 lignes de .tf dupliquées.

Les pièges classiques

⚠️ Type any — Évite type = any. Ça accepte tout et détecte les erreurs trop tard. Sois explicite : string, number, list(string), object({...}).

⚠️ Default mutable — Si tu définis un default = [] pour une liste, Terraform crée une nouvelle liste vide à chaque apply. Ce n’est pas un piège fonctionnel, mais garde-le en tête pour les count conditionnels.

⚠️ Ordre de priorité-var en CLI écrase tout, y compris le .tfvars. En debug, c’est pratique. En CI/CD, c’est une source de bugs si quelqu’un oublie qu’un -var traîne dans le pipeline.

⚠️ Outputs sensibles dans les logs CI — Même avec sensitive = true, un terraform output -json expose tout. Protège les logs de ta CI.

Résumé

Les variables sont le mécanisme de paramétrage fondamental de Terraform :

  • variable = entrées paramétrables avec type, validation et default
  • Types = string, number, bool, list, map, object, tuple
  • Assignation = terraform.tfvars, -var-file, -var, TF_VAR_*
  • output = exposer des valeurs après apply (affichage + inter-modules)
  • locals = valeurs calculées internes, non surchargeables
  • sensitive = masquer les secrets dans les logs (pas dans le state)

Dans le prochain chapitre, on approfondit les locals, les outputs avancés et les expressions conditionnelles — pour écrire du Terraform vraiment élégant.

🖥️ Pratique sur ton propre serveur

Pour suivre Terraform en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.

Obtenir 200$

Articles liés