Terraform : variables, modules et gestion du state
🎯 Objectifs
- ✅ Paramétrer vos configurations avec des variables et outputs
- ✅ Utiliser les locals et data sources
- ✅ Comprendre et gérer le state Terraform
- ✅ Configurer un backend distant pour le travail en équipe
- ✅ Créer et utiliser des modules réutilisables
📋 Prérequis
- Terraform Débutant (workflow init/plan/apply maîtrisé)
📦 Variables
Les variables rendent vos configurations flexibles et réutilisables.
Syntaxe
variable "container_name" {
type = string
description = "Nom du conteneur Docker"
default = "mon-app"
}Types disponibles
| Type | Exemple | Usage |
|---|---|---|
string | "nginx" | Noms, chemins |
number | 8080 | Ports, tailles |
bool | true | Flags on/off |
list(string) | ["a", "b"] | Listes de valeurs |
map(string) | {env = "dev"} | Paires clé-valeur |
object({...}) | {name = string} | Structures complexes |
Fichier variables.tf
variable "image_name" {
type = string
default = "nginx:alpine"
}
variable "external_port" {
type = number
description = "Port exposé sur l'hôte"
default = 8080
}Utilisation dans main.tf
resource "docker_container" "web" {
name = var.container_name
image = var.image_name
ports {
internal = 80
external = var.external_port
}
}Fournir les valeurs
# Via fichier terraform.tfvars
container_name = "prod-nginx"
external_port = 80
# Via ligne de commande
terraform apply -var="external_port=9090"💡 Ordre de priorité : CLI
-var>*.auto.tfvars>terraform.tfvars> valeurdefault.
Validation
variable "external_port" {
type = number
default = 8080
validation {
condition = var.external_port > 1023 && var.external_port < 65536
error_message = "Le port doit être entre 1024 et 65535."
}
}📤 Outputs
Les outputs exposent des valeurs après terraform apply.
Fichier outputs.tf
output "container_id" {
value = docker_container.web.id
description = "ID du conteneur créé"
}
output "access_url" {
value = "http://localhost:${var.external_port}"
}Commandes
terraform output # Affiche tous les outputs
terraform output access_url # Affiche un output spécifique💡 Les outputs servent aussi à passer des valeurs entre modules.
🏷️ Locals
Les locals définissent des valeurs calculées, utiles pour éviter la répétition.
locals {
project = "formation-devops"
env = "dev"
prefix = "${local.project}-${local.env}"
common_tags = {
project = local.project
environment = local.env
managed_by = "terraform"
}
}
resource "docker_container" "web" {
name = "${local.prefix}-nginx"
labels {
label = "project"
value = local.common_tags.project
}
}🔍 Data Sources
Les data sources permettent de lire des ressources existantes non gérées par Terraform.
data "docker_network" "existing" {
name = "mon-reseau"
}
resource "docker_container" "web" {
name = "nginx"
image = "nginx:alpine"
networks_advanced {
name = data.docker_network.existing.id
}
}💡
data= lecture seule.resource= création et gestion.
🗄️ State Management
Le fichier terraform.tfstate est la source de vérité de Terraform - il mappe le code aux ressources réelles.
Commandes de diagnostic
terraform state list # Liste toutes les ressources
terraform state show docker_container.web # Détails d'une ressourceManipulation du state
# Renommer une ressource (après refactoring du code)
terraform state mv docker_container.web docker_container.app
# Retirer une ressource du state (sans la détruire)
terraform state rm docker_container.old⚠️ Ne jamais modifier
terraform.tfstateà la main ! Utilisez uniquement les commandesterraform state.
☁️ Remote State
En équipe, le state local pose problème : conflits, pas de verrouillage, perte possible.
Backend S3 (exemple AWS)
terraform {
backend "s3" {
bucket = "mon-tfstate-bucket"
key = "projet/terraform.tfstate"
region = "eu-west-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}Terraform Cloud (alternative simple)
terraform {
cloud {
organization = "mon-org"
workspaces {
name = "mon-projet"
}
}
}| Avantage | Description |
|---|---|
| 🔒 Verrouillage | Un seul apply à la fois |
| 👥 Partage | Toute l'équipe utilise le même state |
| 💾 Sauvegarde | State stocké de façon sécurisée |
| 📝 Historique | Versions précédentes accessibles |
🧱 Modules
Les modules sont des composants réutilisables d'infrastructure.
Structure d'un module
modules/
└── docker-app/
├── main.tf # Ressources
├── variables.tf # Paramètres d'entrée
└── outputs.tf # Valeurs de sortiemodules/docker-app/main.tf
resource "docker_image" "app" {
name = var.image
}
resource "docker_container" "app" {
name = var.name
image = docker_image.app.image_id
ports {
internal = var.internal_port
external = var.external_port
}
}modules/docker-app/variables.tf
variable "name" { type = string }
variable "image" { type = string }
variable "internal_port" { type = number, default = 80 }
variable "external_port" { type = number }Utiliser le module
module "frontend" {
source = "./modules/docker-app"
name = "frontend"
image = "nginx:alpine"
external_port = 8080
}
module "backend" {
source = "./modules/docker-app"
name = "api"
image = "node:alpine"
internal_port = 3000
external_port = 3000
}💡 Le Terraform Registry propose des milliers de modules publics prêts à l'emploi.
🎯 Points clés
- Les variables rendent les configurations réutilisables - séparez-les dans
variables.tf - Les outputs exposent des valeurs utiles et connectent les modules entre eux
- Le state est sacré - utilisez un backend distant en équipe
- Les modules sont la clé d'une infrastructure maintenable et DRY
- Les data sources lisent l'existant sans le gérer
📚 Ressources
🚀 Prochaines étapes
Vous gérez variables et modules Terraform. Passez aux patterns de production :
- Terraform en production : workspaces, import et CI/CD - Workspaces, CI/CD integration et patterns de production