Automation

Terraform : monter un provider de version sans dérive incontrôlée

Un runbook de production pour qualifier une montée de version de provider Terraform avec lockfile, plan de référence, canary, preuves d’exploitation et rollback explicite.

03 août 2026 terraformiacproviderlockfileautomationdevopsdriftplancanaryobservabilityrunbookrollbackproduction

Une équipe doit mettre à jour un provider Terraform pour corriger un défaut ou débloquer une nouvelle ressource. La modification semble minime : une contrainte de version change, terraform init -upgrade régénère le lockfile et le pipeline produit un plan vert. Pourtant, le plan contient aussi des valeurs recalculées, des champs devenus sensibles, des remplacements ou des différences sur des ressources que la demande ne concernait pas.

Le risque n’est pas seulement le binaire du provider. Une nouvelle version peut lire le state différemment, faire évoluer un schéma, modifier une valeur par défaut ou appeler l’API d’une autre manière. Ce runbook traite donc la montée de version comme un changement de production : figer l’intention, reproduire la toolchain, séparer la dérive existante de l’effet du provider, canaryer le plan, puis décider de déployer, corriger ou rollbacker.

Figer le contrat de changement

Commencez par borner ce qui est autorisé à changer. « Mettre à jour le provider » n’est pas une description exploitable : il faut nommer le provider, les stacks concernées, les ressources sensibles et les différences acceptables.

yaml provider-upgrade-contract.yml
change:
provider: registry.terraform.io/<namespace>/<name>
current_lock: <current-version>
candidate_constraint: <approved-constraint>
terraform_cli: <pinned-version>
canary_stack: platform-nonprod
production_stacks:
  - platform-prod

allowed:
- lockfile checksum and selected provider version
- changes explicitly described in the pull request

block:
- unexplained delete or replacement
- identity, network or encryption change outside scope
- provider alias or subscription mapping change
- state upgrade without a tested return path
- plan that cannot be reproduced in CI

evidence:
- old and candidate lockfiles
- old and candidate plans
- plan JSON classification
- canary apply and runtime checks
- rollback owner and deadline

Conservez le commit, le lockfile, la version de Terraform, la configuration des backends et l’identité d’exécution utilisés par le dernier déploiement réussi. Sans cette référence, une différence de plan peut venir du provider, de la CLI, de l’identité CI ou d’une dérive manuelle.

Reproduire la toolchain avant de comparer

La comparaison n’est fiable que si une seule variable change. Exécutez d’abord un plan avec le code et le lockfile actuels dans le même conteneur CI que la production. Ne régénérez pas encore .terraform.lock.hcl.

bash 01-baseline-plan.sh
set -euo pipefail

terraform version
terraform providers
terraform init -input=false
terraform validate

terraform plan -input=false -out=baseline.tfplan

terraform show -json baseline.tfplan > baseline.plan.json

Un baseline non vide doit être expliqué avant la montée de version. Il représente de la dérive, un changement applicatif déjà présent ou une variation de contexte. L’absorber dans le plan du nouveau provider rendrait impossible l’attribution des différences.

Vérifiez aussi les alias de provider, les modules qui déclarent leurs propres contraintes et les plateformes exécutant Terraform. Le lockfile doit être relu comme un artefact de livraison, pas supprimé pour « repartir proprement ».

Mettre à jour une seule dépendance

Modifiez uniquement la contrainte du provider ciblé. Exécutez l’upgrade sur une branche dédiée, puis inspectez le diff du lockfile : version sélectionnée, contraintes et checksums doivent correspondre au changement attendu.

bash 02-upgrade-target-provider.sh
set -euo pipefail

terraform init -input=false -upgrade

terraform providers lock -platform=linux_amd64 -platform=linux_arm64

git diff -- .terraform.lock.hcl
terraform validate

Adaptez la liste des plateformes à celles réellement utilisées par les postes et runners du projet. N’ajoutez pas une plateforme hypothétique. Si plusieurs providers bougent alors qu’un seul était ciblé, réduisez la contrainte, isolez le changement ou documentez explicitement ce couplage avant de poursuivre.

Ne mélangez pas la montée du provider avec une mise à jour de modules, une nouvelle version de Terraform ou un refactoring HCL. Chaque variable supplémentaire augmente le nombre de causes possibles au premier plan inattendu.

Comparer les plans comme des décisions

Produisez le plan candidat avec le même backend, les mêmes variables et la même identité que le baseline. La sortie texte reste utile pour la relecture humaine ; le JSON permet de classer systématiquement les actions.

bash 03-candidate-plan.sh
set -euo pipefail

terraform plan -input=false -out=candidate.tfplan

terraform show -json candidate.tfplan > candidate.plan.json

jq -r '
.resource_changes[]
| select(.change.actions != ["no-op"])
| [.address, (.change.actions | join(","))]
| @tsv
' candidate.plan.json > candidate.actions.tsv

Relisez au minimum les créations, mises à jour, suppressions et remplacements, puis les changements touchant les identités, secrets, diagnostics, routes, règles de sécurité, stockages stateful et dépendances partagées. Une valeur marquée known after apply n’est pas automatiquement bénigne : identifiez le consommateur et le contrôle post-apply qui prouvera son comportement.

text plan-review.txt
Classer chaque différence
Attendue
  Demandée par le changement
  Effet du provider compris
  Validation post-apply définie

Dérive préexistante
  Visible dans le baseline
  À corriger ou accepter séparément

À bloquer
  Absente du baseline et hors intention
  Delete ou replace non expliqué
  Changement de scope, identité ou région
  Valeur inconnue sans test post-apply
  Ressource critique impossible à restaurer

Le gate n’est pas « zéro différence ». C’est « aucune différence inexpliquée ».

Canaryer sur un scope représentatif

Testez d’abord une stack non productive qui utilise les mêmes modules, aliases, types de ressources et politiques que la production. Un environnement vide valide le téléchargement du provider, pas son comportement sur le patrimoine réel.

Appliquez uniquement le plan enregistré et relu. Après l’apply, exécutez un second plan : il doit être vide ou ne contenir que des écarts précisément compris. Vérifiez ensuite les signaux d’exploitation liés aux ressources modifiées : résolution DNS, santé applicative, authentification, métriques, logs, alertes et jobs automatisés.

yaml provider-canary-gate.yml
before_apply:
- candidate plan approved
- no unexplained replacement
- state backup policy verified
- provider package available to CI
- rollback commit identified

after_apply:
- second plan is empty or explained
- application smoke tests pass
- identities still obtain expected access
- network and DNS probes pass
- logs and metrics remain continuous
- no new provider or API error appears

stop:
- state cannot be read by the previous toolchain
- post-apply plan keeps changing
- production-only resource has no canary equivalent
- runtime validation is ambiguous

Ne confondez pas un workspace avec une isolation automatique. Utilisez le mécanisme déjà adopté par le dépôt pour séparer les states et les environnements ; n’introduisez pas une nouvelle stratégie de state pendant la montée du provider.

Déployer par lots et garder un rollback honnête

Déployez d’abord les stacks à faible impact, puis les dépendances partagées et enfin les scopes les plus critiques. Conservez pour chaque lot le lockfile, le plan approuvé, le résultat de l’apply, le second plan et les preuves runtime.

Avant tout apply, le rollback simple consiste à restaurer la contrainte et le lockfile précédents, puis à confirmer que l’ancienne toolchain lit toujours le state. Après un apply, revenir au binaire précédent ne suffit pas nécessairement : le provider a pu modifier la ressource distante ou faire évoluer le state. Il faut alors construire et relire un plan inverse, ou restaurer la ressource selon son runbook dédié.

text provider-upgrade-decision.txt
Valider
Lockfile limité au provider attendu
Baseline séparé de l'effet de l'upgrade
Aucun delete ou replace inexpliqué
Canary stable après un second plan
Contrôles runtime et observabilité au vert

Rollbacker avant apply
Restaurer contrainte et lockfile
Réinitialiser avec la toolchain approuvée
Reproduire le baseline

Rollbacker après apply
Stopper les lots suivants
Conserver state, plans et logs
Qualifier les changements distants déjà appliqués
Produire un plan inverse ou suivre le runbook de restauration
Prouver le retour du service avant de clore

Conclusion

Une montée de provider Terraform n’est pas validée parce que init, validate et plan réussissent. Elle est validée lorsque le lockfile ne contient que le changement attendu, que le baseline permet d’attribuer chaque différence, que le canary converge vers un plan stable et que les contrôles runtime restent au vert.

La décision de production tient en une règle : déployer seulement les différences comprises et réversibles. Si le provider produit un remplacement, un state illisible ou un comportement non observable, restaurez la toolchain précédente avant l’apply, ou utilisez un plan inverse explicite après l’apply.