Sécurisez vos déploiements : Ne laissez plus vos clés API dans le state

Vos fichiers .tfstate sont de vraies passoires de données sensibles. Apprenez à les chiffrer en temps réel et à automatiser l'injection de secrets pour protéger votre infra.

Introduction : Le talon d'Achille de votre Infrastructure as Code

Schéma conceptuel illustrant la vulnérabilité d'un fichier tfstate local exposé par rapport à un stockage chiffré et sécurisé vers un cloud provider.

Un simple clic sur votre clavier, un rapide terraform apply, et l'intégralité de votre infrastructure cloud s'anime en quelques secondes. Mais derrière cette magie opérationnelle se cache un danger redoutable pour la sécurité de votre entreprise : le stockage en clair de vos données sensibles. Par conception, Terraform a besoin de conserver une cartographie précise de vos ressources pour savoir ce qu'il doit modifier, ajouter ou détruire lors de vos prochaines exécutions.

Ces données de cartographie sont stockées dans les fichiers d'état (state files), généralement nommés terraform.tfstate. Si vous utilisez des variables classiques pour injecter des mots de passe, des jetons d'accès ou des clés privées, sachez que Terraform les écrit mot pour mot, sans aucun chiffrement par défaut, au sein de ce fichier JSON. Si un utilisateur malveillant ou un outil tiers accède à ce fichier, il obtient les clés d'accès directes à l'ensemble de vos serveurs et de vos bases de données de production.

Pourquoi vos fichiers d'état Terraform vous trahissent

La confusion est fréquente chez les ingénieurs système juniors : ils pensent que marquer une variable comme sensitive = true suffit à la protéger. Ce paramètre indique uniquement à Terraform de masquer la valeur dans les journaux d'affichage de votre terminal de contrôle. Dans le fichier physique terraform.tfstate, la donnée reste lisible par n'importe quel éditeur de texte standard. Pour pallier ce problème de sécurité majeur, nous devons impérativement mettre en place un chiffrement fort et externalisé.

Configuration de l'environnement de sécurité

Pour suivre ce guide de mise en production, vous devez disposer des outils de base installés sur votre poste de travail. Nous utiliserons les versions les plus récentes et stables des outils de déploiement d'infrastructure. Assurez-vous d'avoir configuré votre accès à un terminal avec les utilitaires suivants prêts à l'action :

# Vérification des prérequis système
terraform -version
aws --version
vault --version

Le binaire terraform doit être disponible dans sa version actuelle stable. L'outil aws nous permettra d'interagir avec notre fournisseur de cloud pour valider le stockage externe, tandis que vault servira de coffre-fort d'entreprise pour distribuer nos accréditations de manière dynamique sans jamais les écrire dans notre code source.

Chiffrement du State Terraform avec OpenTofu / Terraform Native Providers

La première ligne de défense consiste à interdire le stockage local du fichier d'état sur votre propre machine ou sur le serveur d'intégration continue. Nous allons configurer un backend distant sécurisé hébergé sur un espace de stockage S3 d'AWS. Ce mécanisme assure que le fichier d'état ne touchera jamais votre disque dur local en clair et qu'il sera chiffré à la volée avant même d'être écrit sur les disques durs du fournisseur de cloud.

Mise en place d'un backend S3 sécurisé avec KMS

Pour garantir une sécurité d'un niveau industriel, nous allons coupler notre bucket de stockage à une clé de chiffrement gérée par le service KMS d'AWS. Cela signifie que même si quelqu'un parvenait à s'infiltrer dans votre espace de stockage S3, il lui serait techniquement impossible de lire le fichier sans disposer explicitement des droits d'utilisation de la clé de déchiffrement KMS associée.

terraform {
  required_version = ">= 1.6.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }

  backend "s3" {
    bucket         = "production-tfstate-secure-bucket"
    key            = "infrastructure/production.tfstate"
    region         = "eu-west-3"
    encrypt        = true
    kms_key_id     = "arn:aws:kms:eu-west-3:123456789012:key/a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d"
    dynamodb_table = "terraform-state-locks"
  }
  }

Analysons en détail les paramètres critiques de cette configuration de production pour en comprendre toute la portée défensive :

  • bucket : Spécifie le compartiment de stockage isolé où sera stocké le fichier. Ce compartiment doit avoir ses accès publics strictement désactivés par des stratégies de sécurité AWS.
  • encrypt = true : Force l'utilisation du chiffrement côté serveur (SSE) lors du transfert et du stockage du fichier sur l'infrastructure d'accueil.
  • kms_key_id : Représente l'identifiant unique de votre clé de chiffrement personnalisée. C'est elle qui réalise l'opération mathématique de chiffrement de vos données sensibles.
  • dynamodb_table : Active un verrou de sécurité partagé. Cela évite que deux ingénieurs n'exécutent une modification en même temps, ce qui corromprait instantanément votre fichier d'état.

L'implémentation robuste : Gestion dynamique des secrets via HashiCorp Vault

Intégration du provider Vault dans votre code Terraform

Architecture d'intégration entre Terraform et HashiCorp Vault pour la distribution dynamique des secrets d'infrastructure.

Le chiffrement de votre fichier d'état est indispensable, mais il ne résout pas le problème à la source : comment transmettre des secrets à vos ressources de production sans jamais les écrire dans votre code de configuration ? C'est ici qu'intervient le fournisseur de secrets (secret manager). Au lieu d'écrire un mot de passe de base de données en dur dans un fichier de variables, nous allons demander à Terraform d'aller interroger dynamiquement un coffre-fort sécurisé lors de chaque exécution.

Pour illustrer ce concept, imaginez que Vault soit un réceptionniste d'hôtel ultra-sécurisé. Au lieu de vous donner une clé permanente en métal pour votre chambre, il vous remet un badge magnétique temporaire qui expire automatiquement à la fin de votre séjour. Si quelqu'un vole ce badge après votre départ, il ne lui sera d'aucune utilité.

provider "vault" {
  address          = "https://vault.production.internal:8200"
  skip_child_token = false
}

data "vault_generic_secret" "database_credentials" {
  path = "secret/data/production/database"
}

resource "aws_db_instance" "production_db" {
  allocated_storage   = 50
  engine              = "postgres"
  engine_version      = "16.1"
  instance_class      = "db.r6g.large"
  db_name             = "prod_db"
  username            = data.vault_generic_secret.database_credentials.data["username"]
  password            = data.vault_generic_secret.database_credentials.data["password"]
  skip_final_snapshot = false
}

Comprenons le comportement de ce bloc de code hautement sécurisé :

  • provider "vault" : Initialise la connexion avec votre instance Vault de production via une liaison réseau chiffrée de bout en bout (HTTPS).
  • data "vault_generic_secret" : Interroge le chemin sécurisé spécifié pour récupérer les informations d'authentification sans que l'opérateur humain ne connaisse lui-même ces valeurs sensibles.
  • data.vault_generic_secret.database_credentials.data["password"] : Injecte la valeur du mot de passe directement en mémoire vive lors de l'exécution, évitant ainsi toute persistance physique sur le disque dur de votre serveur d'intégration.

Attention à l'exposition indirecte

Bien que cette méthode évite d'écrire les secrets dans votre code source Git, n'oubliez pas que les valeurs récupérées par le bloc de données seront tout de même écrites dans le fichier de state chiffré. L'utilisation conjointe du backend S3 KMS décrit à la section précédente reste donc indispensable.

Automatisation et cycle de vie des secrets en production

Pour aller encore plus loin dans l'automatisation sécurisée de vos déploiements d'infrastructure, il est recommandé d'utiliser des secrets éphémères. Vault est capable de générer des accès AWS, GCP ou Azure valables uniquement pour la durée de vie de votre déploiement de ressources. Une fois l'opération de déploiement achevée par votre pipeline, les accès sont instantanément révoqués par le système de contrôle de Vault.

Bonnes pratiques et gouvernance opérationnelle

La mise en place technique d'outils de pointe n'est efficace que si elle s'accompagne d'une surveillance continue et d'une validation automatisée de vos configurations. En tant que futur expert de l'automatisation, vous devez mettre en place des gardes-fous automatiques pour empêcher toute erreur humaine d'infecter vos environnements opérationnels.

Audit de code statique avec Tfsec

Avant d'autoriser l'envoi de votre code sur votre branche principale de développement, vous devez configurer un outil d'analyse statique de sécurité. Cet outil agira comme un correcteur orthographique, mais spécialisé dans la détection des vulnérabilités d'infrastructure et des fuites de secrets involontaires.

# Étape d'exécution de l'analyseur statique dans votre pipeline de validation
run_security_audit:
  stage: test
  script:
    - tfsec . --format text --severity high

Résultat du scanner de sécurité :

No problems detected! Your infrastructure configurations comply with the security rules.
[PASSED] AWS001: Encryption enabled on S3 State Bucket.
[PASSED] AWS002: No hardcoded secrets found in database resources.

En imposant cette vérification automatique à chaque modification de code, vous appliquez concrètement le principe du moindre privilège. Les développeurs et les ingénieurs système sont immédiatement alertés si une variable sensible a été définie de manière incorrecte ou si un mécanisme de chiffrement a été accidentellement désactivé au sein de leur espace de travail.

Astuce de déploiement continu

Ajoutez toujours le scanner de sécurité en amont de votre étape de planification de déploiement. Si le scanner détecte une anomalie ou un secret écrit en clair, il doit immédiatement bloquer la suite du pipeline pour empêcher toute génération d'un fichier d'état corrompu.

Conclusion : Vers une infrastructure Zero-Trust

Protéger ses fichiers d'état Terraform et ses secrets d'infrastructure n'est pas une option facultative réservée aux institutions bancaires ou aux services étatiques. C'est une exigence de base pour tout projet professionnel moderne. En déportant le stockage de vos fichiers d'état vers des serveurs de stockage chiffrés par clés matérielles, et en déléguant la gestion de vos mots de passe à un gestionnaire dynamique, vous éliminez la majorité des risques de compromission réseau liés aux outils d'infrastructure.

Prenez le temps d'auditer vos dépôts de code actuels, de migrer vos configurations locales vers des backends distants hautement sécurisés et de sensibiliser vos équipes à ces enjeux critiques de sécurité. La sécurité de votre infrastructure commence dès la première ligne de code que vous écrivez sur votre machine de développement.

Espace commentaire

Écrire un commentaire

Rejoignez la discussion

Vous devez être connecté pour poster un message.

29 commentaires

noel93
Auteur
Avatar de noel93
noel93
Auteur

Tu peux forcer le succès avec une condition dans ton .gitlab-ci.yml ou .github/workflows, mais je te le déconseille fortement.

02/06/2026 à 18:55
imoreno
Membre Actif
Avatar de imoreno
imoreno
Membre Actif

Comment forcer le re-scan de tfsec dans le pipeline si j'ai déjà un test qui passe ?

02/06/2026 à 07:06
noel93
Auteur
Avatar de noel93
noel93
Auteur

Oui, à ne jamais sauter. Un seul terraform apply concurrent et ton state est corrompu. C'est l'enfer à réparer.

02/06/2026 à 01:18
ldacosta
Membre
Avatar de ldacosta
ldacosta
Membre

Le dynamodb_table est vraiment obligatoire pour une petite équipe de 2 personnes ?

01/06/2026 à 13:43
noel93
Auteur
Avatar de noel93
noel93
Auteur

Bien joué. N'oublie pas d'ajouter un .gitignore strict pour éviter toute récidive locale.

01/06/2026 à 09:02
ldescamps
Membre
Avatar de ldescamps
ldescamps
Membre

Top, migration terminée. Plus aucun secret en clair dans mon repo.

31/05/2026 à 23:32
noel93
Auteur
Avatar de noel93
noel93
Auteur

AWS gère la rotation automatique pour toi côté KMS. Terraform n'y verra que du feu, tant que l'ARN de la clé reste le même.

31/05/2026 à 13:51
oceane11
Membre Actif
Avatar de oceane11
oceane11
Membre Actif

Comment on automatise la rotation des clés KMS sans tout casser ?

31/05/2026 à 03:39
noel93
Auteur
Avatar de noel93
noel93
Auteur

Oui, ça renvoie une erreur de type Resource not found. Faut gérer ça avec un data source optionnel si besoin.

30/05/2026 à 22:10
launay-anouk
Membre Actif
Avatar de launay-anouk
launay-anouk
Membre Actif

Le bloc data "vault_generic_secret" est bien, mais quid si le path n'existe pas ? Ça crashe tout le déploiement ?

30/05/2026 à 10:54
noel93
Auteur
Avatar de noel93
noel93
Auteur

Vérifie la variable AWS_PROFILE. Si tu utilises Vault pour générer tes creds, il faut que ton shell soit correctement exporté.

29/05/2026 à 23:35

J'ai des soucis avec le provider AWS, il ne trouve pas les credentials malgré le fichier ~/.aws/credentials.

29/05/2026 à 19:00
noel93
Auteur
Avatar de noel93
noel93
Auteur

Si le chiffrement est activé dans le backend, terraform init échouera si KMS n'est pas accessible. Sécurité par défaut.

29/05/2026 à 10:58
tthomas
Membre
Avatar de tthomas
tthomas
Membre

Est-ce qu'il y a un risque que terraform.tfstate soit uploadé en clair si la connexion KMS échoue ?

29/05/2026 à 03:39
noel93
Auteur
Avatar de noel93
noel93
Auteur

Passe le flag --include-passed ou vérifie ton tfsec.yml de conf. Il scanne par défaut le répertoire courant.

28/05/2026 à 23:22
michelle-denis
Membre Actif
Avatar de michelle-denis
michelle-denis
Membre Actif

J'ai testé tfsec . --severity high mais il ignore mes fichiers .tfvars, c'est normal ?

28/05/2026 à 13:18
noel93
Auteur
Avatar de noel93
noel93
Auteur

Oui, configure le bloc client_auth dans ton provider. C'est même mieux pour éviter de gérer des tokens qui expirent partout.

28/05/2026 à 04:59
rene50
Membre Actif Rédacteur
Avatar de rene50
rene50
Membre Actif Rédacteur

Pour le provider Vault, on peut utiliser des certificats TLS pour l'auth au lieu d'un token fixe ?

27/05/2026 à 18:20

Merci pour l'astuce sur le chiffrement S3. C'est beaucoup plus propre que de stocker ça localement.

27/05/2026 à 13:09
noel93
Auteur
Avatar de noel93
noel93
Auteur

Vérifie que la table a bien une partition key nommée LockID en string. Si c'est mal configuré, le lock ne peut pas s'écrire.

27/05/2026 à 04:08

J'ai configuré dynamodb_table pour le verrouillage mais ça bloque tout le temps. Des conseils pour le troubleshooting ?

26/05/2026 à 16:55
noel93
Auteur
Avatar de noel93
noel93
Auteur

Non, tfsec analyse ton code statique. Pour tes variables d'env, utilise un outil comme trufflehog dans ton pipeline pour scanner les fuites potentielles.

26/05/2026 à 08:57

Est-ce que tfsec détecte bien les secrets stockés dans les variables d'environnement injectées au runtime ?

25/05/2026 à 22:35
noel93
Auteur
Avatar de noel93
noel93
Auteur

La doc est claire : required_version = ">= 1.6.0". Upgrade ton binaire. Ne reste pas sur une vieille version si tu veux utiliser le backend S3 avec chiffrement natif.

25/05/2026 à 17:50
xgallet
Membre
Avatar de xgallet
xgallet
Membre

Impossible d'initialiser, le binaire terraform me dit que la version est trop ancienne. Je suis en 1.4.x.

25/05/2026 à 12:18

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire