Le staging a été créé en cliquant dans le panel Hetzner un vendredi soir. Six mois plus tard, personne ne sait pourquoi le firewall autorise le port 6379 public. La prod, elle, est en Terraform — sauf le bucket S3 ajouté à la main « temporairement ». Résultat : deux vérités, un terraform plan qui veut détruire ce que l'équipe utilise encore.
Terraform promet reproductibilité. Il la tient seulement si le state, les modules et la gouvernance suivent le même niveau d'exigence que le code applicatif.
Providers, ressources et ce qu'on modélise
Les providers européens (Hetzner hcloud, OVH, Scaleway, OpenStack) exposent serveurs, volumes, réseaux privés, DNS, load balancers. Modélisez ce qui change souvent et ce qui doit être traçable :
| Ressource | Intérêt Terraform | Piège |
|---|---|---|
| Serveur / instance | Taille, image, région codées | lifecycle ignore_changes masque drift |
| Firewall / security group | Règles versionnées | Règle manuelle hors TF |
| DNS | Alignement deploy | TTL et propagation oubliés |
| Object storage | Buckets, lifecycle | Clés IAM hors state chiffré |
Si ce n'est pas dans le state, ce n'est pas reproductible — c'est de la dette.
State remote, lock et secrets
Backend remote (S3 + verrou, GitLab HTTP backend, Terraform Cloud) :
- Verrou pendant apply — pas deux applies concurrents.
- Backup du state — il contient parfois des données sensibles.
- Chiffrement at rest ; accès minimal.
Ne commitez jamais terraform.tfstate en clair. Utilisez variables sensibles (TF_VAR_, vault CI) pour tokens API hébergeur.
Modules : DRY sans boîte noire
Modules réutilisables (vpc + subnet + bastion) accélèrent — mais un module fourre-tout opaque décourage la relecture. Exposez variables explicites (instance_type, enable_ipv6, backup_window).
Versionnez modules avec tags Git (?ref=v1.2.0) — pas main flottant. En équipe, terraform fmt et validate en CI avant plan sur MR.
Plan, apply et politique de changement
Workflow sain : MR → terraform plan commenté en CI ; review humaine des destroy et replace ; apply automatisé ou manuel selon criticité.
prevent_destroy sur DB prod. -target réservé aux urgences documentées — sinon état incohérent.
Import progressive des ressources legacy : une ressource à la fois, plan vert avant suivante.
Multi-cloud et hébergeurs européens
Éviter le multi-cloud par défaut — un provider bien maîtrisé bat trois configurations à moitié faites. Pour résidence UE, paramétrez région et vérifiez ressources associées (snapshot region, replica).
Croisez avec contrats sous-traitance RGPD : Terraform ne garantit pas la juridiction — vous choisissez la région dans le code.
Le sommet : infra as code sans gouvernance = clickops déguisé
Reproductible signifie : n'importe quel ingénieur peut recréer staging from scratch — pas seulement que le fichier .tf existe.
Décider et avancer sans angle mort
Configurez un backend remote et verrouillez les accès. Intégrez terraform plan en CI sur chaque merge request. Versionnez les modules avec des tags Git. Planifiez l'import des ressources legacy une par une. Séparez les state par environnement — jamais staging et prod dans le même fichier d'état.
Comparez providers via l'annuaire et le comparateur. Test final : détruire et recréer staging depuis git — durée et surprises documentées.
Questions fréquentes
Pourquoi stocker le state Terraform à distance ?
Le state local sur un laptop empêche le travail d'équipe et se perd au crash disque. Un backend distant verrouille les applies concurrents et historise les changements.
Terraform remplace-t-il Ansible ?
Non — Terraform provisionne l'infrastructure (serveurs, réseau, DNS, buckets) ; Ansible ou cloud-init configure l'OS et les services. Les deux se complètent.
Comment éviter le drift ?
Plan régulier en CI, interdiction de modifications manuelles non reportées dans le code, et import documenté pour les ressources legacy.
Faut-il un workspace par environnement ?
Oui — state séparés staging et production. Jamais le même state pour deux environnements critiques.
Terraform utile se lit dans un plan revu par un humain — pas dans un apply lancé depuis un laptop sans témoin.