Retour aux articles

    5 erreurs Terraform de débutant à éviter absolument

    Par Bastien Genestal

    20 février 2026

    TerraformIaCDevOps
    5 erreurs Terraform de débutant à éviter absolument

    Il y a quelques années, je me souviens encore de la première fois où j'ai exécuté une commande terraform apply en production. J'avais les mains moites, le cœur battant, et cette petite voix dans ma tête qui me disait : "Es-tu vraiment sûr de ce que tu fais ?". Spoiler alert : je ne l'étais pas totalement. Aujourd'hui, en tant que Lead Cloud Architect, je regarde en arrière avec un mélange de tendresse et d'effroi face aux erreurs monumentales que j'ai pu commettre à mes débuts.

    Terraform est un outil fantastique. C'est le standard de l'industrie pour l'Infrastructure as Code (IaC). Mais c'est aussi un outil qui vous laisse tirer une balle dans votre propre pied avec une précision chirurgicale si vous ne faites pas attention. Contrairement au code applicatif où un bug peut "juste" faire planter une fonctionnalité, une erreur Terraform peut effacer une base de données de production ou exposer vos secrets d'entreprise au monde entier en quelques secondes.

    L'objectif de cet article n'est pas de vous faire peur, mais de vous offrir le raccourci que je n'ai pas eu. Nous allons décortiquer cinq erreurs classiques, techniques et architecturales, que font presque tous les débutants (et même certains séniors). Prenez un café, installez-vous confortablement, et analysons ensemble comment éviter de transformer votre infrastructure en champ de ruines.

    Le stockage local du State ou la recette du désastre collaboratif

    L'une des premières choses que l'on apprend, c'est que Terraform maintient l'état de votre infrastructure dans un fichier appelé terraform.tfstate. Au début, tout semble simple : vous lancez votre code, le fichier se crée sur votre ordinateur, et tout fonctionne. C'est ici que le piège se referme.

    Pourquoi le stockage local est une bombe à retardement

    Lorsque vous travaillez seul sur un projet personnel, garder le "state" sur votre machine (le backend local) est acceptable. Mais dès l'instant où une deuxième personne rejoint l'équipe, ou que vous souhaitez mettre en place un pipeline CI/CD, le stockage local devient votre pire cauchemar. Comme l'explique ce guide sur les risques de corruption du fichier d'état, ce fichier est la source de vérité absolue pour Terraform. Si vous l'avez sur votre ordinateur, votre collègue ne l'a pas. S'il essaie de déployer une modification, Terraform pensera que les ressources n'existent pas et tentera de les recréer, provoquant des conflits de noms ou, pire, des duplications coûteuses.

    De plus, si votre disque dur grille, vous perdez la correspondance entre votre code et la réalité. Vous vous retrouvez alors à devoir faire de l'import manuel, une tâche fastidieuse et propice aux erreurs. Mais le problème le plus insidieux reste l'absence de "locking" (verrouillage). Sans un mécanisme centralisé pour dire "Je suis en train de modifier l'infrastructure", deux ingénieurs peuvent lancer un déploiement simultanément. Le résultat ? Une condition de course (race condition) qui corrompt le fichier d'état, rendant votre infrastructure ingérable.

    La solution du Backend Remote avec verrouillage

    La bonne pratique, dès le jour un, est d'utiliser un backend distant. Sur AWS, le standard historique consistait à utiliser un bucket S3 pour le stockage et une table DynamoDB pour le verrouillage (State Locking). Bonne nouvelle : AWS a récemment simplifié la donne en introduisant le verrouillage natif directement via S3, illustrant l'évolution constante des services managés chez AWS, GCP et Azure, éliminant ainsi le besoin de gérer une ressource DynamoDB supplémentaire pour cette tâche critique.

    La gestion naïve des secrets et des données sensibles

    C'est l'erreur qui fait le plus transpirer les responsables de la sécurité. En débutant, on a tendance à vouloir aller vite. On a besoin d'un mot de passe pour une base de données RDS ou d'une clé d'API pour un service tiers. La tentation est grande de les écrire "juste pour tester" dans le fichier variables.tf ou, pire, directement dans le code des ressources.

    La persistance des données en clair

    Même si vous utilisez des variables d'environnement pour passer vos secrets à Terraform, il y a un détail technique crucial que beaucoup ignorent : le fichier terraform.tfstate stocke les valeurs des ressources en clair. Oui, vous avez bien lu. En effet, les fichiers d'état Terraform stockent les données sensibles en clair même si vous marquez une variable comme sensitive = true dans votre code, car cela empêche seulement son affichage dans la sortie console (stdout) lors d'un plan ou d'un apply.

    Si vous committez votre fichier d'état dans Git (ce qu'il ne faut absolument jamais faire, cf. le point précédent), ou si votre bucket S3 n'est pas correctement sécurisé, n'importe qui ayant accès à ce fichier peut lire vos mots de passe de base de données, vos clés privées TLS, et vos tokens d'accès. C'est une faille de sécurité majeure.

    Sécuriser la chaîne de bout en bout

    Pour gérer cela comme un pro, il faut adopter une approche par couches. D'abord, bannissez l'écriture de secrets en dur dans vos fichiers .tf. Privilégiez les gestionnaires de secrets natifs comme AWS Secrets Manager, Azure Key Vault ou l'incontournable HashiCorp Vault. Si vos besoins exigent une approche plus "cloud agnostique" ou si vous souhaitez conserver une trace de vos secrets directement dans votre dépôt Git, ne le faites jamais en clair. Utilisez des outils comme git-crypt ou sops. Ces solutions chiffrent vos fichiers sensibles avant qu'ils ne soient poussés sur le serveur, garantissant que seul un utilisateur possédant la clé de déchiffrement puisse les lire.

    Plutôt que de passer des mots de passe via des variables, votre code Terraform devrait s'appuyer sur des "Data Sources" pour récupérer ces informations dynamiquement au moment de l'exécution. De cette façon, le secret n'apparaît jamais dans votre code source. Enfin, n'oubliez pas le maillon faible : le fichier d'état. Puisque Terraform y stocke inévitablement les données pour ses calculs, le chiffrement de votre backend (comme le chiffrement côté serveur sur S3) et une politique IAM restrictive sont non négociables. Traitez votre fichier d'état avec le même niveau de paranoïa que vos clés privées.

    L'architecture monolithique et le refus de la modularité

    Quand on commence, on a tendance à tout mettre dans un seul fichier main.tf, ou à la rigueur, à séparer les fichiers par service (réseau, compute, base de données) mais dans un seul et même dossier racine. Au début, c'est rapide. Mais à mesure que l'infrastructure grandit, cette approche monolithique devient un enfer opérationnel.

    Le problème du Blast Radius

    Imaginez que vous ayez toute votre infrastructure (VPC, bases de données de production, serveurs d'application, DNS) dans un seul projet Terraform. Chaque fois que vous lancez un terraform plan, l'outil doit rafraîchir l'état de toutes ces ressources via les API du fournisseur Cloud. Cela pose deux problèmes majeurs. Premièrement, la lenteur : sur de grosses infrastructures, un simple plan peut prendre 10 à 15 minutes.

    Deuxièmement, et c'est le plus grave, le "Blast Radius" (rayon d'impact). Ce concept de 'Terralith' ou architecture monolithique présente des risques majeurs : si vous faites une petite modification sur un Security Group, mais que vous faites une erreur de frappe qui affecte une ressource globale, vous risquez de casser toute la production. Une architecture monolithique ne permet pas d'isoler les risques.

    Diviser pour mieux régner avec les modules

    L'architecture mature repose sur l'utilisation intensive de modules et la séparation stricte des états, des piliers essentiels pour une Infrastructure as Code (IaC) évolutive. Ne dupliquez pas votre code pour les environnements de Dev, Staging et Prod. Créez plutôt des modules réutilisables (par exemple un module "app-standard" regroupant ASG, ALB et règles de sécurité) et appelez-les avec des variables spécifiques. Pour isoler réellement les risques, vous devez séparer physiquement les fichiers d'état. Votre réseau (VPC) doit avoir son propre cycle de vie, indépendant de vos bases de données ou de vos clusters Kubernetes. Voici à quoi ressemble une hiérarchie de dossiers saine pour un projet d'envergure :

    terraform/
    ├── networking/ (VPC, Subnets...)
    ├── eks/ (Cluster Kubernetes)
    ├── cloudwatch/
    ├── cloudtrail/
    ├── app1/
    │   ├── rds/
    │   ├── asg/
    │   └── cloudfront/
    └── app2/
        ├── ec2/
        ├── rds/
        └── s3_images/</code>
    

    Grâce à cette structure, une modification sur le CloudFront de l'App 1 n'a techniquement aucune chance d'impacter le VPC ou la base de données de l'App 2. Chaque dossier possède son propre terraform init et son propre backend distant. Comme mentionné plus haut concernant le Blast Radius, cette approche est la seule garantie d'une infrastructure robuste, où le rayon d'impact est maîtrisé et les temps d'exécution restent ultra-rapides.

    Workspaces vs tfvars : le dilemme de l'isolation des environnements

    Une question revient systématiquement lorsqu'on commence à structurer ses projets : comment gérer proprement le déploiement sur plusieurs environnements (Dev, Staging, Prod) ? La tentation est grande d'utiliser la fonctionnalité native des Terraform Workspaces, mais c'est souvent là qu'apparaissent les premières frictions opérationnelles.

    Le mirage des Workspaces CLI

    Sur le papier, les workspaces sont séduisants. Ils permettent d'utiliser le même code et de basculer d'un état à l'autre avec une simple commande terraform workspace select. C'est un outil puissant pour tester des fonctionnalités isolées ou créer des environnements éphémères. Cependant, les utiliser pour isoler durablement la Production du reste est une pratique risquée.

    Le principal danger est l'invisibilité. Contrairement à une structure de dossiers, rien dans votre éditeur de code ne vous indique visuellement sur quel environnement vous travaillez. Une erreur d'inattention, un terraform destroy lancé alors que vous pensiez être en 'dev' alors que vous étiez en 'prod', et le désastre arrive. De plus, comme les workspaces partagent souvent le même backend et le même code source, vous vous retrouvez vite à polluer vos fichiers avec des conditions complexes (count = terraform.workspace == "prod" ? 3 : 1) qui rendent la lecture pénible.

    La clarté par la séparation physique

    Pour des environnements pérennes, la recommandation des experts penche massivement vers l'utilisation de fichiers de variables (.tfvars) dédiés ou, mieux encore, une organisation par répertoires pour favoriser le passage à l'échelle. En utilisant des fichiers dev.tfvars, staging.tfvars et prod.tfvars, vous rendez les configurations explicites. Chaque déploiement nécessite de passer le fichier en paramètre (-var-file="prod.tfvars""), ce qui ajoute une couche de validation consciente.

    Pour une isolation totale et une sécurité maximale, privilégiez des dossiers distincts. Cela permet non seulement d'isoler les fichiers d'état (State), mais aussi de gérer des versions de modules différentes entre la Dev et la Prod, évitant ainsi de casser votre infrastructure critique lors d'une mise à jour de module un peu trop ambitieuse.

    L'ignorance du Refactoring et des blocs Moved

    L'infrastructure est vivante. Elle évolue. Ce que vous avez nommé aws_instance.web aujourd'hui devra peut-être s'appeler aws_instance.frontend demain, ou être déplacé dans un module enfant pour plus de propreté. Pour un débutant, c'est souvent une impasse. On se dit : "Si je change le nom dans le code, Terraform va détruire l'ancienne ressource et en créer une nouvelle". Et c'est exactement ce qu'il va faire par défaut.

    La peur de la perte de données

    Sur des ressources stateless (sans état) comme un groupe de sécurité, ce n'est pas très grave. Mais sur une base de données de production ou un bucket S3 contenant des pétaoctets de données, une destruction/recréation est inacceptable. Pendant longtemps, la seule solution était d'utiliser la commande CLI terraform state mv. C'était une opération chirurgicale effrayante : il fallait manipuler le fichier d'état directement en ligne de commande, souvent à l'aveugle, avec un risque élevé de corruption si on se trompait dans les chemins des ressources.

    L'élégance du bloc Moved

    Heureusement, les versions modernes de Terraform (depuis la 1.1) ont introduit le bloc moved. Comme le souligne cet article sur l'abandon de la commande manuelle terraform state mv, c'est une revelation que j'aurais aimé avoir plus tôt. Au lieu de taper des commandes CLI périlleuses, vous documentez le déplacement directement dans votre code HCL.

    Concrètement, vous écrivez un bloc qui dit : "Ce qui était avant aws_instance.web est maintenant aws_instance.frontend". Lors du prochain terraform plan, l'outil va lire ce bloc, comprendre qu'il s'agit d'un renommage et non d'une destruction/création, et proposer de migrer l'état sans toucher à l'infrastructure réelle. Cela a deux avantages immenses. D'abord, c'est sécurisé car Terraform gère la logique. Ensuite, cela permet de versionner vos migrations, garantissant que vos collègues comprendront exactement ce qui se passe lors de la revue de code.

    Conclusion

    Débuter avec Terraform est un voyage passionnant vers l'automatisation et la maîtrise du Cloud. Cependant, la courbe d'apprentissage est parsemée de pièges qui ne pardonnent pas. En évitant le stockage local, en sécurisant vos secrets, en modularisant votre architecture, en comprenant les risques de destruction accidentelle liés aux index lors de l'utilisation de count, et en utilisant les blocs moved pour vos refontes, vous vous placez déjà dans le top tiers des praticiens.

    L'Infrastructure as Code n'est pas seulement une question d'écriture de code ; c'est une question de gestion du cycle de vie et de responsabilité opérationnelle. Ces erreurs, je les ai faites pour que vous n'ayez pas à les reproduire. Alors, configurez votre backend distant, chiffrez vos données, et bon déploiement !

    Bastien Genestal

    Bastien Genestal

    Lead Cloud Architect @ Log'in Line

    En tant que Lead Cloud Architect, je gère une équipe d'architectes et SRE pour gérer les clusters de nos clients au quotidien. Je suis aussi un grand fan de grimpe 🧗‍♂️

    LinkedIn

    Obtenez des réductions Cloud

    En tant que partenaires, on vous fait profiter de réductions chez AWS (-4%), GCP (-3%) et Scaleway (-8%)

    Mise en place en 1 heureSans engagement

    À lire aussi

    Pourquoi migrer d'Ingress vers la Gateway API avec Kgateway en 2026 ?

    Découvrez pourquoi nous migrons vers Kgateway et la Gateway API : performance Envoy, gouvernance réseau et fonctionnalités natives pour l'IA générative.

    L'Infogérance Cloud en 2026 : Définition et Enjeux Réels
    24 janvier 2026

    L'Infogérance Cloud en 2026 : Définition et Enjeux Réels

    Actualités
    Infrastructure

    Découvrez la réalité de l'infogérance cloud en 2026 : un levier stratégique pour la performance, la sécurité et la maîtrise des coûts de votre entreprise.