La commande était correcte. Le code était relu. Les tests passaient. Et pourtant, en trois minutes, j’ai supprimé un groupe de sécurité, deux règles de routage et un point de terminaison privé sur l’environnement de production d’un client — parce que mon terminal pointait sur le mauvais état.
Quarante minutes d’indisponibilité partielle. Aucune donnée perdue, ce qui relève de la chance plus que de la conception. Et une certitude : le problème n’était pas mon attention, c’était l’absence de dispositif qui rende cette erreur impossible.
Voici les sept garde-fous que nous posons désormais systématiquement, dans l’ordre où ils apportent le plus de sécurité par heure investie.
Étape 1 — Externaliser l’état et activer le verrouillage
Un état local est une bombe à retardement : il n’est ni partagé, ni sauvegardé, ni protégé contre les exécutions concurrentes. Première opération, toujours : basculer sur un backend distant avec versionnage et chiffrement au repos.
Le verrouillage est la partie non négociable. Sans lui, deux applications simultanées — un collègue et votre CI, typiquement — écrivent sur le même fichier et produisent un état incohérent. La récupération est manuelle, longue, et se fait toujours sous pression. Activez également le versionnage du bucket : c’est votre seule capacité à revenir à un état antérieur.
Étape 2 — Rendre le plan obligatoire, et surtout lisible
Interdire apply sans plan préalable est acquis dans la plupart des équipes. Le vrai sujet est ailleurs : un plan que personne ne lit ne protège de rien.
Trois règles rendent le plan exploitable. Générer le plan dans un fichier et l’appliquer depuis ce fichier, jamais régénérer entre les deux — sinon vous appliquez autre chose que ce qui a été relu. Faire remonter en tête de la sortie le décompte des destructions, qui est la seule ligne qui compte vraiment. Et publier le plan en commentaire de la pull request, pour que la revue porte sur l’effet et non sur le code.
Le seuil que nous appliquons : toute destruction non nulle exige une approbation explicite d’une seconde personne. Pas une validation tacite — un clic distinct de celui de la revue de code.
Étape 3 — Protéger les ressources critiques, en connaissant les limites
Le bloc lifecycle avec prevent_destroy est le réflexe standard sur les bases de données, les buckets de stockage et les points de terminaison privés. Il est utile. Il est aussi largement surestimé.
Trois angles morts à connaître. Il ne protège pas du remplacement forcé : modifier un attribut immuable déclenche une destruction suivie d’une création, et le garde-fou ne s’applique pas de la même manière selon les fournisseurs. Il ne protège pas de la suppression du bloc lui-même — si quelqu’un retire la ressource du code, Terraform ne voit plus aucune contrainte. Et il ne protège pas d’un terraform state rm suivi d’une opération manuelle.
La conclusion pratique : doublez toujours la protection côté fournisseur cloud. Activez la protection contre la suppression directement sur l’instance de base de données. Ce niveau-là survit à toutes les erreurs de code.
Étape 4 — Séparer physiquement les environnements
C’est le garde-fou qui aurait empêché mon incident, et de loin le plus rentable.
Les workspaces Terraform sont pratiques et dangereux : même configuration, même backend, sélection implicite. Une variable d’environnement oubliée, un workspace select non exécuté, et vous appliquez la configuration de recette sur l’état de production.
La séparation par backend distinct rend la classe d’erreur impossible, pas seulement improbable. Un état par environnement, dans un bucket distinct, idéalement dans un compte cloud distinct. Le coût est réel — duplication de code, gestion de plusieurs pipelines — mais il s’agit du prix d’une garantie structurelle plutôt que d’une vigilance individuelle.
Si vous migrez une infrastructure existante, c’est l’étape la plus longue : les déplacements d’état se font ressource par ressource, avec vérification à chaque pas. Prévoyez deux à trois jours et ne la faites jamais un vendredi.
Votre production et votre recette partagent le même état ?
Nous auditons vos configurations Terraform et pilotons la séparation des états sans interruption de service. Le diagnostic prend une journée.
Lance-toiÉtape 5 — Restreindre l’identité qui exécute Terraform
Question simple, réponse souvent gênante : avec quels droits tourne votre pipeline Terraform ? Dans la majorité des équipes que nous auditons, la réponse est « administrateur du compte ».
Trois principes suffisent à corriger. Une identité par environnement, jamais partagée. Aucun humain ne dispose des droits d’application en production — seule la CI les possède, ce qui force le passage par le flux relu de l’étape 2. Et les permissions de suppression sont refusées explicitement sur les ressources classées critiques, indépendamment de ce que dit le code.
Ce dernier point est le filet de sécurité ultime : même un plan malveillant ou une erreur de code ne peut pas supprimer ce que l’identité n’a pas le droit de supprimer. C’est le même raisonnement que celui appliqué aux comptes de service applicatifs, sujet que traitent en profondeur nos confrères de WebGuard Agency.
Étape 6 — Automatiser la revue de plan par politique
La revue humaine fatigue. Après le trentième plan de la semaine, personne ne compte réellement les lignes de destruction. L’automatisation par politique reprend ce travail.
Le principe : le plan est exporté en format machine, puis évalué par un moteur de règles avant l’application. Quatre règles couvrent l’essentiel des incidents réels.
Une : refuser tout plan qui détruit une ressource portant une étiquette « critique ». Deux : refuser tout plan dont le nombre de destructions dépasse un seuil — chez nous, cinq — sans dérogation explicite. Trois : refuser toute ressource de stockage créée sans chiffrement. Quatre : refuser toute règle réseau ouvrant un port d’administration sur l’ensemble d’internet.
Ces règles se rédigent en une journée et attrapent ensuite, indéfiniment, des erreurs que la fatigue laisse passer.
Étape 7 — Répéter une reprise réelle avant d’en avoir besoin
Le dernier garde-fou n’empêche rien. Il décide de la durée de l’incident quand les six premiers ont échoué.
Une fois par trimestre, sur un compte de test, provoquez délibérément la panne : corrompez un état, supprimez une ressource critique, et chronométrez la remise en service. Trois questions à documenter — où se trouve la version antérieure de l’état, qui a le droit de la restaurer, et combien de temps prend la reconstruction complète depuis le code.
La plupart des équipes découvrent à ce moment-là que leur infrastructure n’est pas entièrement reconstructible : des ressources créées à la main n’ont jamais été importées, et personne ne le savait. C’est précisément le genre de constat qui justifie un profil d’architecte cloud dédié plutôt qu’une compétence diffuse dans l’équipe — un arbitrage que nous détaillons dans notre guide sur le recrutement de profils backend seniors, et qui rejoint la question de l’outillage IA en production traitée chez Plug-Tech.
Questions fréquentes
prevent_destroy suffit-il à protéger une base de données ?
Non, et c’est un piège classique. Il empêche Terraform de détruire la ressource, mais ne protège pas contre un remplacement forcé déclenché par la modification d’un attribut immuable, ni contre la suppression du bloc de code lui-même — auquel cas Terraform ne voit plus la contrainte. Il faut le combiner avec une protection côté fournisseur cloud, activée directement sur l’instance.
Faut-il un état Terraform par environnement ou des workspaces ?
Pour de la production, préférez des états séparés dans des backends distincts, voire des comptes cloud distincts. Les workspaces partagent la même configuration et le même backend : une erreur de sélection reste possible, et c’est le scénario d’incident le plus fréquent. La séparation physique rend la classe d’erreur impossible plutôt qu’improbable.
Le verrouillage d’état est-il vraiment nécessaire pour une petite équipe ?
Oui, dès la deuxième personne, et même à une seule personne dès qu’une CI peut exécuter Terraform. Deux applications concurrentes sur un même état produisent un fichier incohérent, dont la récupération est longue et manuelle. Le verrouillage coûte quelques lignes de configuration ; sa réparation coûte une journée.
Combien de temps prend la mise en place de ces sept garde-fous ?
Sur une infrastructure existante de taille moyenne, comptez trois à cinq jours pour les six premiers, dont l’essentiel passe dans la séparation des états — l’opération la plus délicate car elle suppose des déplacements ressource par ressource. La septième étape demande une demi-journée par trimestre et reste la plus souvent négligée.
L’erreur humaine n’est pas une cause racine. C’est un symptôme.
Nous mettons en place les dispositifs qui rendent vos incidents d’infrastructure structurellement impossibles, plutôt que simplement improbables.
Lance-toi