
Versionner un module Terraform consiste à associer un tag Git sémantique à chaque version stable du code. Cela permet aux projets consommateurs de choisir précisément quelle version utiliser, d’éviter les régressions et de planifier les mises à jour. Sans versionnement, modifier un module impacte immédiatement tous les projets qui le consomment.
Prérequis : avoir lu Utiliser un module local et Utiliser un module du Registry.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre pourquoi le versionnement est indispensable
- Appliquer le versionnement sémantique (SemVer) aux modules
- Créer des tags Git pour versionner un module
- Référencer une version spécifique depuis un projet consommateur
- Mettre à jour un module de façon contrôlée
Pourquoi versionner
Section intitulée « Pourquoi versionner »Le problème sans versionnement
Section intitulée « Le problème sans versionnement »Avec un module local (source = "../modules-partages/reseau"), toute modification du module est immédiatement visible par tous les projets qui le consomment. Cela signifie qu’un changement dans le module peut casser un projet en production sans prévenir.
modules-partages/reseau/ ← une modification ici...├── projet-dev/ ← ...impacte ici├── projet-staging/ ← ...et ici└── projet-prod/ ← ...et ici aussi !La solution : les versions
Section intitulée « La solution : les versions »Le versionnement découple le rythme de développement du module du rythme d’adoption par les projets. Chaque projet choisit quand monter en version :
module "reseau" { source = "git::https://gitlab.example.com/infra/modules.git//reseau?ref=v1.2.0" # ↑ ce projet utilise la v1.2.0 — il ne sera pas impacté par des changements ultérieurs}Le versionnement sémantique (SemVer)
Section intitulée « Le versionnement sémantique (SemVer) »Le standard utilisé par Terraform et le Registry est le Semantic Versioning (SemVer) : MAJOR.MINOR.PATCH.
| Composant | Quand l’incrémenter | Exemple |
|---|---|---|
| MAJOR | Changement incompatible (breaking change) | 1.0.0 → 2.0.0 |
| MINOR | Nouvelle fonctionnalité rétrocompatible | 1.0.0 → 1.1.0 |
| PATCH | Correction de bug rétrocompatible | 1.0.0 → 1.0.1 |
Exemples concrets pour un module réseau
Section intitulée « Exemples concrets pour un module réseau »| Modification | Type | Version |
|---|---|---|
| Corriger le message d’erreur d’une validation | PATCH | 1.0.0 → 1.0.1 |
Ajouter une variable optionnelle tags avec default = {} | MINOR | 1.0.1 → 1.1.0 |
Renommer cidr en network_config (breaking) | MAJOR | 1.1.0 → 2.0.0 |
| Supprimer une variable existante | MAJOR | 1.1.0 → 2.0.0 |
| Ajouter un nouvel output | MINOR | 1.1.0 → 1.2.0 |
Versionner avec des tags Git
Section intitulée « Versionner avec des tags Git »-
Initialiser un dépôt Git pour les modules :
Fenêtre de terminal cd modules-partages/git initgit add .git commit -m "feat: module réseau initial" -
Créer un tag pour la première version :
Fenêtre de terminal git tag -a v1.0.0 -m "Version initiale du module réseau"git push origin v1.0.0 -
Après une modification mineure (ajout d’une variable optionnelle) :
Fenêtre de terminal # Modifier le code...git add .git commit -m "feat(reseau): ajouter variable tags optionnelle"git tag -a v1.1.0 -m "Ajout de la variable tags"git push origin v1.1.0 -
Après un breaking change (renommage de variable) :
Fenêtre de terminal # Modifier le code...git add .git commit -m "BREAKING CHANGE(reseau): renommer cidr en network_config"git tag -a v2.0.0 -m "Renommage cidr → network_config"git push origin v2.0.0
Référencer une version dans un projet
Section intitulée « Référencer une version dans un projet »Depuis un dépôt Git
Section intitulée « Depuis un dépôt Git »module "reseau" { source = "git::https://gitlab.example.com/infra/modules.git//reseau?ref=v1.2.0" # ↑ URL Git ↑ chemin du module dans le dépôt ↑ tag Git}La syntaxe ?ref=v1.2.0 fige la version. Même si de nouvelles versions sont publiées, ce projet reste sur v1.2.0.
ref peut pointer vers un tag, une branche ou un commit SHA, mais pour un module partagé entre équipes, un tag Git sémantique reste le choix le plus lisible et le plus sûr.
Depuis le Terraform Registry
Section intitulée « Depuis le Terraform Registry »module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "5.21.0" # ↑ contrainte de version gérée par le Registry}Contraintes de version
Section intitulée « Contraintes de version »Les mêmes contraintes que pour les providers s’appliquent :
version = "1.2.0" # exactement 1.2.0version = "~> 1.2.0" # >= 1.2.0 et < 1.3.0 (patchs uniquement)version = "~> 1.2" # >= 1.2.0 et < 2.0.0 (évolutions compatibles de la même majeure)version = ">= 1.0, < 2.0" # plage explicite| Contrainte | Recommandation | Cas d’usage |
|---|---|---|
"1.2.0" | Production | Reproductibilité maximale |
"~> 1.2.0" | Staging | Recevoir les patchs automatiquement |
"~> 1.2" | Développement | Recevoir les évolutions compatibles de la même majeure |
Workflow de mise à jour
Section intitulée « Workflow de mise à jour »Quand une nouvelle version d’un module est disponible, chaque projet décide quand l’adopter :
-
Lire le changelog de la nouvelle version pour identifier les changements
-
Mettre à jour la contrainte de version dans le bloc
module:module "reseau" {source = "git::https://gitlab.example.com/infra/modules.git//reseau?ref=v1.3.0"# ↑ v1.2.0 → v1.3.0} -
Relancer
terraform initpour télécharger la nouvelle version :Fenêtre de terminal terraform init -upgrade# -upgrade force le re-téléchargement même si une version est déjà en cache -
Exécuter
terraform planpour voir les changements prévus :Fenêtre de terminal terraform plan# Vérifier qu'aucune destruction inattendue n'apparaît -
Appliquer si le plan est correct
Organisation d’un dépôt multi-modules
Section intitulée « Organisation d’un dépôt multi-modules »Pour un dépôt Git contenant plusieurs modules, la convention est :
terraform-modules/├── reseau/│ ├── versions.tf│ ├── variables.tf│ ├── main.tf│ └── outputs.tf├── volume/│ ├── versions.tf│ ├── variables.tf│ ├── main.tf│ └── outputs.tf├── vm/│ └── ...├── CHANGELOG.md└── README.mdLe tag versionne tout le dépôt. Si les modules évoluent à des rythmes différents, deux approches existent :
| Approche | Avantage | Inconvénient |
|---|---|---|
| Mono-dépôt (1 tag pour tout) | Simple à gérer | Un changement dans reseau/ force un nouveau tag même si vm/ n’a pas changé |
| Multi-dépôts (1 dépôt par module) | Versionnement indépendant | Plus de dépôts à maintenir |
Pour commencer, le mono-dépôt est recommandé. Passez au multi-dépôts quand les modules évoluent à des rythmes très différents.
CHANGELOG
Section intitulée « CHANGELOG »Un fichier CHANGELOG.md à la racine du dépôt de modules documente l’historique des versions :
# Changelog
## [1.2.0] - 2025-03-31### Added- Variable `tags` optionnelle sur le module réseau
## [1.1.0] - 2025-03-15### Added- Output `configuration` structuré sur le module réseau
## [1.0.0] - 2025-03-01### Added- Module réseau initial (libvirt_network)Ce format suit la convention Keep a Changelog.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
terraform init ne télécharge pas la nouvelle version | Version en cache | Ajouter -upgrade à terraform init |
ref not found avec source Git | Tag inexistant ou faute de frappe | Vérifier avec git tag -l sur le dépôt |
| Changements inattendus après mise à jour | Breaking change non documenté | Revenir à l’ancienne version et lire le changelog |
version ... does not match (Registry) | Contrainte trop restrictive | Élargir la contrainte ou spécifier la version exacte |
À retenir
Section intitulée « À retenir »- Sans versionnement, modifier un module impacte immédiatement tous les projets
- Le versionnement sémantique (MAJOR.MINOR.PATCH) communique la nature du changement
- Tout changement qui oblige à modifier le bloc
moduleest un breaking change (MAJOR) - Les tags Git annotés (
git tag -a) sont le mécanisme de versionnement ?ref=vX.Y.Z(Git) ouversion = "X.Y.Z"(Registry) figent la version dans un projet-upgradesurterraform initforce le re-téléchargement d’une version- Mettez à jour un environnement à la fois : dev → staging → prod