Le mythe des variables masquées et l'inévitable fuite du TFState
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.
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
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
Pour ceux qui galèrent avec Vault, est-ce qu'on peut utiliser le Secret Manager d'AWS à la place ?
Vérifie ta relation de confiance dans ton rôle IAM. Ton rôle doit autoriser l'action
sts:AssumeRoleWithWebIdentitypour ton fournisseur d'identité OIDC.J'ai un souci avec l'authentification OIDC sur GitLab CI. J'ai bien configuré le provider, mais j'ai une erreur 403 Forbidden au moment du plan.
Content que ça t'ait ouvert les yeux. À ne jamais faire en prod : utiliser la clé KMS par défaut (SSE-S3).
Elle est gérée par AWS et tu n'as aucun contrôle sur les politiques d'accès. Crée une CMK (Customer Managed Key) pour avoir un contrôle total sur qui peut déchiffrer ton
terraform.tfstate.Super article. J'ai toujours cru que
sensitive = truesuffisait pour protéger mes accès DB. Grosse erreur de ma part.Par contre, pour le backend S3, si je n'ai pas de clé KMS dédiée, je peux utiliser celle par défaut d'AWS ou c'est déconseillé ?