Les fondamentaux de Terraform : ce qu’un débutant doit vraiment savoir
La plupart des tutoriels Terraform commencent par la syntaxe. C’est la partie la moins importante. Voici les six idées sur lesquelles l’outil est construit, un exemple Azure complet, et les quelques habitudes qui distinguent ceux qui utilisent Terraform de ceux qui se battent avec.
Dans cet article
- 1. Vous décrivez la destination, pas l’itinéraire
- 2. Les providers sont la façon dont Terraform parle à tout le reste
- 3. La ressource est l’unité de tout
- 4. Le plan est le produit
- 5. L’état est ce qui fait tout fonctionner — et ce que vous devez protéger
- 6. Variables, sorties et modules : comment cela passe à l’échelle
- Une première configuration complète
- Les erreurs qui coûtent réellement aux équipes
- Et ensuite
Terraform est un outil qui permet de décrire une infrastructure dans des fichiers texte et de laisser un programme faire en sorte que le cloud corresponde à cette description. C’est toute l’idée. Le reste — le langage, les commandes, l’écosystème — n’existe que pour la servir.
Si les débutants peinent, ce n’est pas parce que Terraform est difficile, mais parce qu’ils apprennent les commandes avant de comprendre à quoi elles servent. Cet article prend donc le chemin inverse : les idées d’abord, puis le plus petit exemple réel qui les met toutes en œuvre, puis les erreurs qui coûtent le plus cher aux nouvelles équipes.
1. Vous décrivez la destination, pas l’itinéraire
Un script shell dit fais ceci, puis cela, puis encore cela. Exécutez-le deux fois : soit il échoue à la seconde exécution, soit il crée les choses en double. Ce style est impératif.
Terraform est déclaratif. Vous écrivez ce qui doit exister — un groupe de ressources, un compte de stockage avec tels paramètres, un réseau virtuel avec telles plages d’adresses — et Terraform détermine ce qu’il faut faire pour y parvenir. Exécutez-le deux fois sur un parc déjà conforme : il ne fait rien, et c’est la bonne réponse.
C’est le changement de perspective essentiel. Vous n’écrivez pas un programme qui construit une infrastructure. Vous écrivez une description d’infrastructure, et le programme, c’est Terraform.
2. Les providers sont la façon dont Terraform parle à tout le reste
Terraform en lui-même ne sait rien d’Azure, d’AWS, de GitHub ou du DNS. Il sait lire une configuration, calculer des différences et appeler des plugins. Ces plugins sont les providers, et il en existe un pour pratiquement chaque plateforme dotée d’une API.
Sur Azure, vous en rencontrerez trois :
azurerm— les ressources Azure : groupes de ressources, réseaux, stockage, calcul, presque tout ce que l’on associe à « Azure »azuread— les objets Entra ID : groupes, utilisateurs, applications, principaux de serviceazapi— une fine couche au-dessus de l’API REST Azure, pour les types de ressources ou propriétés queazurermne prend pas encore en charge
Un provider se déclare une seule fois, avec une contrainte de version, puis chaque bloc de ressource de votre configuration l’utilise. Figer la version n’est pas facultatif en pratique. Une montée de version du provider peut changer ce que Terraform veut faire sur votre parc, et c’est à vous de choisir quand cela se produit.
3. La ressource est l’unité de tout
Un bloc de ressource décrit une chose que le provider sait créer. Il a un type, un nom local que vous choisissez, et des arguments :
resource "azurerm_resource_group" "platform" {
name = "rg-platform-weu"
location = "westeurope"
}
Lisez-le ainsi : le provider azurerm doit garantir qu’un groupe de ressources existe avec ce nom dans cette région, et dans mon code je l’appellerai platform.
Le nom local compte plus que les débutants ne l’imaginent. C’est par lui que les autres blocs font référence à celui-ci :
resource "azurerm_storage_account" "logs" {
name = "stplatformlogsweu"
resource_group_name = azurerm_resource_group.platform.name
location = azurerm_resource_group.platform.location
account_tier = "Standard"
account_replication_type = "LRS"
}
Cette référence — azurerm_resource_group.platform.name — fait deux choses. Elle transmet une valeur, évidemment. Moins évidemment, elle informe Terraform d’une dépendance : le compte de stockage ne peut pas être créé avant que le groupe de ressources existe, donc Terraform ordonnera les opérations correctement sans que vous ayez à le préciser. L’essentiel de l’ordonnancement d’une configuration Terraform est déduit de cette manière. Vous aurez rarement besoin de l’écrire.
4. Le plan est le produit
Le flux de travail Terraform tient en quatre commandes, et l’une d’elles est la raison pour laquelle on fait confiance à l’outil en production :
terraform init # télécharge les providers, se connecte au backend d’état
terraform plan # compare la configuration à la réalité ; montre ce qui changerait
terraform apply # applique les changements (après avoir réaffiché le plan)
terraform destroy # supprime tout ce que cette configuration gère
plan est la commande importante. Elle lit votre configuration, lit l’état courant, demande au provider ce qui existe réellement, et affiche un différentiel : ceci sera créé, ceci sera mis à jour sur place, ceci sera détruit et recréé. Rien ne se passe dans le cloud.
C’est cette dernière catégorie qu’il faut lire à chaque fois. Certains changements ne peuvent pas se faire sur place — renommer un compte de stockage, changer la zone de disponibilité d’une VM — et la réponse honnête de Terraform est de supprimer puis de reconstruire. Il vous le dira. C’est à vous de le remarquer.
Un plan qui annonce 0 to add, 0 to change, 0 to destroy n’est pas un résultat ennuyeux. C’est la preuve que votre description et votre parc sont d’accord, et c’est l’état dans lequel vous devriez être entre deux changements délibérés.
5. L’état est ce qui fait tout fonctionner — et ce que vous devez protéger
Après chaque apply, Terraform écrit un fichier d’état : le registre de chaque ressource qu’il gère et de l’identifiant réel de chacune. C’est ainsi que Terraform sait, la fois suivante, que azurerm_resource_group.platform est le groupe de ressources portant cet identifiant, et non un nouveau groupe à créer.
Trois conséquences en découlent, et chacune fait mal au débutant qui l’apprend par accident :
L’état doit être partagé. S’il vit sur votre ordinateur portable, le plan de votre collègue ignore ce que vous avez créé et tentera de le créer à nouveau. Sur Azure, la réponse habituelle est un compte de stockage avec un conteneur blob comme backend, les baux de blob assurant le verrouillage pour que deux personnes ne puissent pas appliquer en même temps.
L’état peut contenir des secrets. Un mot de passe généré, une chaîne de connexion, une clé — si une ressource la renvoie, Terraform la stocke, en clair. Le compte de stockage qui héberge votre état mérite le même contrôle d’accès que les systèmes qu’il décrit.
L’état est la mémoire de Terraform, pas celle du cloud. Si quelqu’un modifie une ressource dans le portail, le fichier d’état est désormais faux. Le prochain plan proposera de remettre les choses en place — ce qui est généralement ce que vous voulez, et parfois une mauvaise surprise. Cet écart entre l’état et la réalité s’appelle la dérive, et la détecter est la raison pour laquelle les équipes matures exécutent un plan à intervalle régulier même quand rien ne change.
6. Variables, sorties et modules : comment cela passe à l’échelle
Une fois qu’une configuration fonctionne, trois constructions l’empêchent de devenir un mur de copier-coller.
Les variables sont les entrées. Déclarez-les avec un type et une description, et le même code se déploie en développement et en production avec un fichier de valeurs différent.
variable "environment" {
type = string
description = "Nom court de l’environnement, utilisé dans les noms de ressources."
}
Les sorties sont les valeurs que vous voulez récupérer — une adresse IP, un identifiant de ressource, un nom dont une autre configuration a besoin.
Les modules sont des dossiers de code Terraform que vous appelez comme une fonction. Un module « compte de stockage avec nos paramètres obligatoires » signifie que le chiffrement, les règles réseau et les paramètres de diagnostic sont décidés une fois, revus une fois, et appliqués partout. Microsoft publie les Azure Verified Modules précisément dans ce but, et les utiliser est un meilleur premier pas que d’écrire les vôtres.
Un débutant devrait d’abord tout écrire à plat. On ne comprend à quoi sert un module qu’après avoir ressenti la douleur qu’il supprime.
Une première configuration complète
Voici l’ensemble : un provider, un groupe de ressources, un compte de stockage, une sortie. C’est volontairement petit, et cela fonctionne.
terraform {
required_version = ">= 1.9"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
}
}
provider "azurerm" {
features {}
subscription_id = var.subscription_id
}
variable "subscription_id" {
type = string
description = "Souscription Azure cible."
}
variable "environment" {
type = string
default = "dev"
}
resource "azurerm_resource_group" "platform" {
name = "rg-platform-${var.environment}-weu"
location = "westeurope"
tags = {
environment = var.environment
managed_by = "terraform"
}
}
resource "azurerm_storage_account" "logs" {
name = "stlogs${var.environment}weu"
resource_group_name = azurerm_resource_group.platform.name
location = azurerm_resource_group.platform.location
account_tier = "Standard"
account_replication_type = "LRS"
min_tls_version = "TLS1_2"
}
output "storage_account_id" {
value = azurerm_storage_account.logs.id
}
Connectez-vous avec az login, lancez terraform init, puis terraform plan, et lisez ce qu’il propose : deux ressources à ajouter, rien à modifier, rien à détruire. Appliquez. Relancez ensuite un plan et constatez qu’il n’annonce aucun changement. Modifiez alors min_tls_version, lancez un plan, et voyez qu’il s’agit d’une mise à jour sur place. Changez ensuite le nom du compte de stockage, lancez un plan, et voyez qu’il s’agit d’un remplacement. Vous avez maintenant vu chaque type de changement que Terraform peut effectuer, et vous en comprenez davantage que bien des personnes qui l’utilisent depuis un an.
Terminez par terraform destroy pour que rien ne vous soit facturé pendant la nuit.
Les erreurs qui coûtent réellement aux équipes
Modifier dans le portail. Chaque changement manuel est une dérive, et chaque dérive est un futur plan avec lequel il faudra discuter. Décidez dès le premier jour que les ressources gérées par Terraform se modifient via Terraform, et donnez au portail un accès en lecture seule pour le faire respecter.
Un état local au-delà de la première semaine. Passez à un backend distant avant qu’une seconde personne touche au code. Migrer plus tard est possible, et désagréable.
Lancer apply sans lire le plan. Le plan est l’endroit où Terraform vous annonce qu’il est sur le point de supprimer la base de données. Il le dira clairement, en rouge, et il le fera quand même si vous tapez yes.
Des versions non figées. Un provider qui se met à jour tout seul entre deux exécutions de pipeline, c’est un plan qui change pour une raison qui ne vient pas de vous. Figez Terraform, figez chaque provider, montez de version délibérément.
Des secrets dans le code. Les mots de passe dans les fichiers .tfvars finissent dans Git. Utilisez une référence Key Vault, un secret de pipeline ou une valeur générée — et rappelez-vous qu’elle se retrouvera quand même dans l’état, une raison de plus de verrouiller le backend d’état.
Renommer une ressource dans le code. Changez le nom local d’un bloc de ressource et Terraform voit une ressource disparue et une nouvelle à créer — une destruction suivie d’une reconstruction. Un bloc moved lui indique qu’il s’agit de la même chose. Apprenez-le avant de refactoriser quoi que ce soit qui vous tient à cœur.
Et ensuite
Vous savez maintenant à quoi sert Terraform, comment il décide de ce qu’il fait, et ce qu’il attend de vous en retour. Les prochaines étapes, dans l’ordre :
- Placez l’état dans un backend sur compte de stockage, et faites-en le seul.
- Exécutez plan et apply depuis un pipeline avec une identité managée, pas depuis un ordinateur portable avec vos propres identifiants.
- Adoptez les Azure Verified Modules pour les types de ressources que vous déployez le plus.
- Planifiez un plan quotidien sur la production et traitez toute dérive comme un constat à corriger.
L’outil offre bien davantage — workspaces, sources de données, for_each, blocs dynamiques, import, contrôles de politique. Rien de tout cela n’est nécessaire tant que les quatre étapes ci-dessus ne sont pas franchies, et tout devient beaucoup plus facile à apprendre une fois qu’elles le sont.