Tuto : Sécurisez vos fichiers d'état Terraform sans effort

Vos fichiers .tfstate contiennent vos mots de passe en clair. Apprenez à les chiffrer, à utiliser des providers de secrets et à automatiser l'encryption au repos dès maintenant.

Le mythe des variables masquées et l'inévitable fuite du TFState

Un administrateur système devant un écran affichant un fichier JSON Terraform contenant des mots de passe en clair surlignés en rouge, avec un arrière-plan sombre de lignes de code matricielles et un bouclier cybernétique fissuré.

Vous avez probablement déjà configuré l'argument sensitive = true sur vos variables Terraform en pensant que vos secrets étaient désormais à l'abri des regards indiscrets. C'est une erreur classique de débutant qui peut coûter très cher à votre entreprise. Cette option masque uniquement la valeur dans la sortie standard de votre terminal lors d'un déploiement, mais ne chiffre absolument rien au repos.

La dure réalité du fonctionnement interne de Terraform est que chaque ressource provisionnée, chaque mot de passe généré et chaque clé d'API récupérée est stockée de manière brute, transparente et lisible dans votre fichier state file (TFState). Si un attaquant accède à votre compartiment de stockage d'état, il accède instantanément aux clés d'accès de l'intégralité de votre infrastructure.

Les fondations d'un environnement hermétique

Avant d'entamer la refonte de nos configurations, nous devons préparer notre environnement de travail avec des outils professionnels. Nous utiliserons le client Terraform, l'interface de ligne de commande AWS, ainsi que le binaire de HashiCorp Vault pour la gestion dynamique des secrets. Assurez-vous d'installer ces dépendances sur votre poste de travail local avant de poursuivre.

# Installation de l'utilitaire de validation et des CLI nécessaires
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt-get update && sudo apt-get install terraform vault awscli -y

Résultat:

Terraform v1.8.0 on linux_amd64
Vault v1.15.0 on linux_amd64
aws-cli/2.15.0 Python/3.11.6 Linux/6.5.0-generic

Ces commandes configurent le dépôt officiel HashiCorp et installent les dernières versions stables des outils indispensables. L'installation conjointe de Terraform et de Vault va nous permettre de concevoir un pipeline où les secrets ne transitent jamais par des fichiers de configuration statiques.

Anatomie d'une vulnérabilité : Où dorment vos secrets ?

Pourquoi sensitive = true ne protège pas vos données au repos

Pour bien comprendre le problème, imaginez que le fichier d'état de Terraform est comme un journal intime de votre infrastructure. Même si vous demandez à Terraform de ne pas lire les secrets à haute voix dans le terminal, il les écrit tout de même noir sur blanc dans ce journal pour pouvoir suivre l'état de vos ressources lors des prochaines exécutions. Si ce journal est stocké localement ou sur un serveur de fichiers non sécurisé, n'importe qui peut l'ouvrir et lire vos identifiants.

Examinons de plus près la structure d'un fichier d'état par défaut généré lors de la création d'une base de données de test. Ce fichier JSON contient l'intégralité des configurations sans aucun filtre de confidentialité.

{
  "version": 4,
  "terraform_version": "1.8.0",
  "resources": [
    {
      "mode": "managed",
      "type": "aws_db_instance",
      "name": "production_db",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "address": "production-db.c123456789.us-east-1.rds.amazonaws.com",
            "username": "admin_db_user",
            "password": "SuperSecretPassword123!",
            "port": 5432
          }
        }
      ]
    }
  ]
}

Comme vous pouvez le constater dans la section attributes, le mot de passe de production apparaît de manière totalement transparente. Si ce fichier se retrouve par mégarde sur un dépôt Git public ou sur un serveur de partage mal configuré, vos systèmes sont immédiatement compromis.

Schéma illustrant le cycle de vie du fichier d'état Terraform et le risque de fuite des secrets en clair vers des destinations non sécurisées.

Ce schéma détaille le cycle de transmission de l'état Terraform. Le flux rouge représente le danger critique où un fichier d'état local est commité par accident ou envoyé vers un espace de stockage S3 accessible publiquement, permettant à un acteur malveillant de collecter les identifiants en clair. À l'inverse, le flux vert démontre l'approche sécurisée vers un stockage distant protégé par chiffrement fort et politiques d'accès strictes.

De la théorie à la pratique : Implémentation d'une architecture sécurisée

Étape 1 : Interroger Vault de manière dynamique

Plutôt que d'écrire des mots de passe en dur dans vos variables ou de les passer via des fichiers de variables .tfvars qui risquent de fuiter, nous allons connecter Terraform à HashiCorp Vault. Vault agira comme un coffre-fort hautement sécurisé. Terraform ira chercher le secret à la volée pendant l'exécution, l'utilisera pour configurer la ressource, et aucune donnée sensible ne sera présente dans vos fichiers de configuration.

provider "vault" {
  address = "https://vault.internal.enterprise.com:8200"
  # Authentification sécurisée via jeton à usage unique en production
}

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

resource "aws_db_instance" "production_db" {
  allocated_storage   = 20
  engine              = "postgres"
  engine_version      = "15.4"
  instance_class      = "db.t3.micro"
  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 = true
}

Dans ce bloc de code, le provider Vault est initialisé sans informations de connexion en dur, s'appuyant sur des variables d'environnement sécurisées. La source de données vault_generic_secret interroge dynamiquement le chemin sécurisé du coffre-fort au moment du terraform plan. Les identifiants de la base de données ne sont ainsi jamais visibles dans le code source de l'application.

Étape 2 : Configuration d'un Backend S3 robuste avec chiffrement KMS

Un schéma d'architecture AWS sécurisé montrant un bucket S3 de stockage d'état Terraform verrouillé par une clé KMS personnalisée, avec des flèches d'authentification IAM sécurisées et une table de verrouillage DynamoDB.

Pour assurer la pérennité et la confidentialité de nos déploiements en équipe, nous devons utiliser un stockage distant hautement sécurisé. Nous allons implémenter un chiffrement au repos (Encryption at Rest) sur notre backend de stockage d'état en utilisant une clé de chiffrement gérée par le service de gestion de clés (KMS) d'AWS, combinée à une table DynamoDB pour verrouiller l'état et éviter les écritures simultanées conflictuelles.

terraform {
  backend "s3" {
    bucket         = "prod-enterprise-terraform-state-bucket"
    key            = "infrastructure/production/terraform.tfstate"
    region         = "eu-west-3"
    encrypt        = true
    dynamodb_table = "prod-terraform-state-locks"
    kms_key_id     = "arn:aws:kms:eu-west-3:123456789012:key/abc12345-d123-4567-89ab-cdef12345678"
  }
}

L'attribut encrypt = true impose un chiffrement côté serveur sur le compartiment S3. La directive kms_key_id spécifie une clé KMS gérée par le client, garantissant que seul le personnel ou le rôle IAM disposant explicitement des droits de déchiffrement de cette clé pourra lire le contenu du fichier d'état. Enfin, le dynamodb_table prévient toute corruption d'état par double écriture.

Limites du chiffrement de backend

Bien que le backend S3 chiffre le fichier d'état au repos, toute personne ou pipeline CI/CD ayant les permissions de lire le bucket S3 pourra toujours déchiffrer et lire le contenu en clair si elle dispose des droits KMS d'accompagnement. Vous devez restreindre drastiquement ces accès.

Stratégies avancées : Automatisation et détection proactive

Authentification sans clé avec OIDC et rotation automatique

La gestion de la sécurité des accès exige d'éliminer définitivement les clés d'accès AWS à longue durée de vie de vos serveurs de CI/CD (comme GitHub Actions ou GitLab CI). À la place, nous allons utiliser le mécanisme OpenID Connect (OIDC). Ce protocole permet à votre plateforme de CI/CD de s'authentifier auprès d'AWS via des jetons temporaires d'une durée de vie de quelques minutes seulement, appliquant ainsi à la lettre le principe du moindre privilège.

# Exemple partiel de workflow GitHub Actions configurant l'accès sécurisé sans clé
name: Terraform Deployment
on:
  push:
    branches: [ main ]

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Configure AWS Credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-actions-terraform-role
          aws-region: eu-west-3

      - name: Terraform Init & Apply
        run: |
          terraform init
          terraform apply -auto-approve

La section permissions est cruciale ici : elle accorde le droit de générer un jeton OIDC temporaire. Grâce à l'action officielle AWS, GitHub s'authentifie directement auprès de l'IAM AWS sans qu'aucune clé secrète permanente (AWS_ACCESS_KEY_ID) ne soit stockée dans les secrets de votre dépôt.

Mise en place de garde-fous : Détecter les secrets avant le commit

Pour s'assurer qu'aucun secret ne s'échappe de l'environnement de développement, il est capital d'automatiser le contrôle du code avant même qu'il ne soit poussé sur un serveur distant. Nous utilisons un outil d'analyse statique capable de détecter les clés d'API, mots de passe ou certificats codés en dur dans nos fichiers Terraform.

Solution de Détection Type d'Analyse Points Forts Usage Recommandé
Gitleaks Analyse de l'historique Git et pré-commit Ultra-rapide, basé sur des expressions régulières avancées Bloquer les commits locaux non conformes
Trivy / tfsec Analyse statique (AST) du code Terraform Détecte les erreurs de configuration cloud et les secrets Intégration dans les pipelines CI/CD
HashiCorp Vault Gestionnaire dynamique de secrets Génère des identifiants éphémères et auto-expirables Gestion des secrets en cours d'exécution

Le tableau ci-dessus met en évidence la complémentarité des outils. L'utilisation conjointe d'un outil local comme Gitleaks pour stopper les erreurs humaines et d'un système de secrets dynamiques comme Vault garantit une sécurité à 360 degrés, de l'écriture du code jusqu'au déploiement final en production.

Adopter une posture Zero Trust avec Terraform

La sécurité de vos déploiements d'infrastructure ne doit jamais reposer sur la chance ou sur de vagues règles de bonne conduite. En configurant un stockage d'état distant chiffré par une clé KMS dédiée, en bannissant les variables statiques au profit de requêtes dynamiques vers un gestionnaire de secrets (Secrets Managers) comme Vault, et en automatisant vos déploiements via OIDC, vous construisez une forteresse inexpugnable autour de vos environnements de production.

En tant que professionnel du DevOps, votre rôle est de concevoir des systèmes où l'erreur humaine est rendue techniquement impossible par la structure même de la plateforme. Ne laissez plus jamais vos fichiers d'état à la portée de n'importe quel utilisateur ou d'un conteneur CI compromis : verrouillez vos accès dès aujourd'hui et passez à une architecture véritablement professionnelle.

Espace commentaire

Écrire un commentaire

Rejoignez la discussion

Vous devez être connecté pour poster un message.

30 commentaires

auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Bonne initiative. N'oublie pas de supprimer tes vieilles clés d'accès IAM une fois que tout est en place.

26/05/2026 à 02:44
rlabbe
Membre
Avatar de rlabbe
rlabbe
Membre

Super article, je vais appliquer la partie OIDC dès demain sur mon pipeline.

25/05/2026 à 17:28
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Ton serveur doit avoir un accès limité au net. Télécharge le fichier GPG manuellement et installe-le en local.

25/05/2026 à 06:34
lacroix-louis
Membre Actif
Avatar de lacroix-louis
lacroix-louis
Membre Actif

J'ai eu une erreur étrange lors de l'installation de Vault : gpg: keyserver receive failed.

24/05/2026 à 20:41
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Va dans la console AWS, regarde les propriétés de ton objet dans S3, et vérifie que la section 'Server-side encryption' affiche bien ta clé KMS.

24/05/2026 à 11:18

Comment je peux vérifier que mon état est bien chiffré après le déploiement ?

24/05/2026 à 05:41
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Oui, utilise l'ARN complet pour éviter toute confusion entre plusieurs régions ou comptes.

23/05/2026 à 18:17

Le guide est top, merci. Par contre, pour le kms_key_id, c'est bien l'ARN complet qu'il faut mettre ?

23/05/2026 à 13:48
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Vérifie bien le path dans ton Vault. N'oublie pas que le path peut varier selon si tu utilises le moteur kv-v1 ou kv-v2.

23/05/2026 à 06:21

J'ai une erreur sur data.vault_generic_secret. Il me dit que le chemin n'existe pas.

22/05/2026 à 21:21
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Seulement si tu as les droits kms:Decrypt sur la clé utilisée. Sinon, tu récupéreras un fichier chiffré illisible.

22/05/2026 à 15:08
matthieu35
Membre
Avatar de matthieu35
matthieu35
Membre

Question bête : si mon S3 est chiffré, est-ce que je peux toujours lire le contenu avec le CLI aws s3 cp ?

22/05/2026 à 07:22
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Non, ils sont complémentaires. tfsec analyse la structure de ton code, Gitleaks fouille dans l'historique des commits pour voir si tu n'as pas déjà leaké un secret.

22/05/2026 à 01:17
leon66
Membre
Avatar de leon66
leon66
Membre

Est-ce que tfsec remplace vraiment Gitleaks ?

21/05/2026 à 19:55
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Le token est censé être éphémère. Si ton déploiement dure plus d'une heure, c'est que ton infra est trop complexe ou que ton plan est trop lourd. Découpe ton code en modules.

21/05/2026 à 12:56

J'ai testé l'authentification OIDC mais mon token expire trop vite. Une idée ?

21/05/2026 à 01:08
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Il suffit d'ajouter le bloc backend dans ton code et de relancer terraform init. Il va te demander automatiquement de migrer l'état existant.

20/05/2026 à 20:03
guillaume71
Membre Actif
Avatar de guillaume71
guillaume71
Membre Actif

Comment je fais pour migrer mon état actuel qui est en local vers le backend S3 sans tout casser ?

20/05/2026 à 11:24
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

C'est optionnel mais fortement recommandé. Sans ça, si deux personnes lancent un déploiement en même temps, tu vas corrompre ton état et passer une très mauvaise journée.

20/05/2026 à 06:05
yrossi
Membre
Avatar de yrossi
yrossi
Membre

Dans ton exemple de backend, tu utilises dynamodb_table. C'est obligatoire ou optionnel ?

19/05/2026 à 20:13
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

C'est le prix à payer pour ne pas se faire pirater. Optimise ton fichier .gitleaksignore pour ignorer les dossiers inutiles comme .terraform/.

19/05/2026 à 13:45
thibault83
Membre
Avatar de thibault83
thibault83
Membre

J'ai mis en place Gitleaks comme pré-commit. Ça ralentit mes commits, c'est normal ?

19/05/2026 à 03:41
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Le bucket doit être créé manuellement AVANT d'initialiser Terraform. Terraform ne peut pas gérer son propre backend s'il n'existe pas encore.

18/05/2026 à 19:17
margaux00
Membre
Avatar de margaux00
margaux00
Membre

Merci pour le tuto. Installation nickel via apt-get. Par contre, mon terraform plan échoue car il ne trouve pas le bucket S3 défini dans le backend.

18/05/2026 à 12:02
auguste-hebert
Auteur Actif
Avatar de auguste-hebert
auguste-hebert
Auteur Actif

Oui, tu peux utiliser le data source aws_secretsmanager_secret_version. C'est moins agnostique que Vault mais très efficace si tu es 100% sur AWS.

18/05/2026 à 07:03

Rejoindre la communauté

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

S'inscrire