Business Digital

Intégrer Vault avec Terraform pour workflows IaC sécurisés — tutoriel 2026

13 دقائق للقراءة

📍 Article principal : Vault Associate. Ce tutoriel intègre Vault avec Terraform pour des workflows IaC sécurisés sans secrets dans le state.

L’intégration Vault + Terraform est la combinaison gagnante du DevSecOps moderne. Terraform provisionne l’infrastructure, Vault gère les secrets nécessaires à cette infrastructure (mots de passe RDS, API keys cloud, certificats TLS). Ensemble, ils permettent un workflow IaC complet où aucun secret n’apparaît dans le code Git ni dans le state Terraform. Ce tutoriel détaille le provider Vault officiel, les data sources pour lire les secrets dynamiquement, les patterns de bootstrap.

Provider Vault dans Terraform

HashiCorp maintient un provider Vault officiel pour Terraform qui expose toutes les ressources Vault en HCL. Configuration provider de base : spécifier l’adresse Vault et le mode d’authentification. Recommandation : ne jamais hardcoder les credentials dans le bloc provider — passer par variables d’environnement (VAULT_ADDR, VAULT_TOKEN) ou via OIDC depuis la CI.

Le provider permet deux usages distincts. Premier : gérer Vault lui-même via Terraform — créer auth methods, secrets engines, policies, mounts. Cette approche IaC pour Vault transforme la configuration en code versionné, reproductible, auditable. Deuxième : lire les secrets depuis Vault pour les utiliser dans d’autres ressources Terraform — par exemple récupérer un mot de passe RDS depuis Vault et l’injecter dans une ressource AWS.

Lire les secrets via data sources

Pour lire un secret KV stocké dans Vault, utiliser la data source vault_kv_secret_v2 : data "vault_kv_secret_v2" "db_password" { mount = "kv"; name = "production/database" }. Le secret peut ensuite être référencé dans n’importe quelle ressource : password = data.vault_kv_secret_v2.db_password.data["password"]. Le secret n’apparaît jamais en clair dans le code, et n’est pas stocké dans le state Terraform si on configure correctement (mark sensitive=true).

Pour les dynamic secrets, utiliser la data source correspondante. vault_database_secret_backend_static_role pour les credentials PostgreSQL, vault_aws_access_credentials pour AWS, etc. Chaque appel Terraform plan/apply génère un nouveau credential — pour les opérations courtes, c’est parfait. Pour les opérations longues, basculer sur Vault Agent qui gère le renewal et expose les secrets aux processus locaux.

Pattern de bootstrap : œuf et poule

Question classique : si Terraform a besoin de Vault pour ses secrets, et Vault a besoin d’être déployé pour fournir des secrets, comment résoudre cette dépendance circulaire ? Pattern recommandé : deux dépôts Terraform distincts. Dépôt 1 (bootstrap) déploie Vault lui-même avec credentials initiaux gérés en dehors de Vault — par exemple via cloud KMS pour l’auto-unseal et root token sealed dans un coffre. Dépôt 2 (workloads) utilise Vault pour ses secrets et déploie le reste de l’infrastructure.

Cette ségrégation prévient les boucles de dépendance et limite la surface d’attaque. Le dépôt bootstrap est rarement modifié (une fois Vault déployé), avec accès très restreint à quelques admins. Le dépôt workloads tourne fréquemment avec les pipelines normaux. Cette architecture est la pratique recommandée par HashiCorp pour les déploiements en production sérieux.

Authentication Terraform → Vault via OIDC

Pour l’authentification Terraform vers Vault depuis la CI, OIDC est le pattern moderne. GitLab et GitHub Actions exposent un JWT signé pour chaque job. Vault peut valider ce JWT via JWT auth method et délivrer un token Vault aux permissions adaptées. Plus aucun token Vault statique à gérer dans la CI — chaque job s’authentifie avec son identité unique.

Configuration côté Vault : activer JWT auth, configurer le provider OIDC pointant vers GitLab ou GitHub, créer un rôle qui mappe les claims JWT (project_id, ref, environment) aux policies. Configuration côté CI : ajouter id_tokens dans le job, faire appel à vault login avec le JWT, récupérer le token Vault, l’utiliser pour terraform plan/apply. Cette mécanique élégante élimine totalement les credentials statiques de la CI — sécurité maximale.

Cas concret : déploiement multi-cloud sécurisé

Pour ancrer dans un cas réel, voici un workflow type. La PME ouest-africaine déploie un service web sur Hostinger Cloud VPS avec base de données PostgreSQL. Vault stocke les credentials Hostinger API, les credentials PostgreSQL admin, les API keys Mobile Money. Terraform lit ces secrets via data sources Vault, provisionne le VPS via le provider Hostinger ou un compatible, configure la base, déploie l’application.

Aucun secret n’apparaît dans le code, le state Terraform reste propre (les valeurs sensibles sont marquées et n’apparaissent pas en clair), la rotation des credentials se fait dans Vault sans modifier Terraform. Pour les apprenants ouest-africains qui débutent, Hostinger propose un excellent rapport qualité-prix avec panneau en français pour pratiquer ce workflow. Au-delà de la pratique, cette architecture devient le standard de production pour les organisations sérieuses.

Erreurs fréquentes

ErreurCauseSolution
Secrets dans le state Terraformsensitive=true non appliquéMarquer toutes les variables et outputs sensibles avec sensitive=true
VAULT_TOKEN dans GitTentation hardcodingToujours via VAULT_TOKEN env var ou OIDC depuis CI
Lease expiré pendant terraform applyTTL trop courtAugmenter TTL des credentials utilisés par Terraform à 2-4h
Boucle dépendance Vault-TerraformSingle repo monolithiqueSéparer bootstrap (Vault deployment) et workloads (apps)

Réalités du terrain en Afrique francophone

Pour les PME ouest-africaines, l’intégration Vault + Terraform constitue le standard de maturité DevSecOps. Cette compétence rend immédiatement éligible aux missions premium pour fintechs, banques, télécoms — secteurs où la sécurité des credentials est critique et où peu de profils maîtrisent réellement cette intégration. Pour les freelances, mettre en avant cette double compétence sur LinkedIn et Malt augmente significativement le taux de propositions reçues. Couplée aux certifications Terraform Associate et Vault Associate, c’est l’arsenal complet attendu par les recruteurs internationaux.

Pour étoffer le tableau

🔝 Retour à l’article principal : Vault Associate. Tutoriels précédents : HA, dynamic secrets, AppRole/JWT. Documentation provider Vault Terraform : registry.terraform.io/providers/hashicorp/vault.

L’intégration Vault + Terraform marque l’aboutissement du parcours DevSecOps moderne. Pour les apprenants ouest-africains qui maîtrisent les deux outils, le marché professionnel s’ouvre largement — missions internationales remote, postes Senior dans les grands groupes, conseil stratégique pour les transformations digitales. Cet investissement en certifications combinées (Terraform Associate + Vault Associate) constitue l’un des meilleurs ratios coût-bénéfice du marché tech francophone en 2026 (informations vérifiées en avril 2026, susceptibles d’évoluer ; vérifier la source officielle avant toute décision technique).

Étape 1 : préparer l’environnement Vault et Terraform sur Ubuntu 24.04

Avant de connecter Vault à Terraform, installez les deux binaires sur votre poste de travail ou un runner GitLab basé à Dakar ou Abidjan. HashiCorp distribue des paquets APT signés ; évitez les builds non officiels qui retardent les correctifs CVE.

# Installation Vault et Terraform (Ubuntu 24.04 LTS)
wget -O- https://apt.releases.hashicorp.com/gpg | \
  sudo gpg --dearmor -o /usr/share/keyrings/hashicorp.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp.gpg] \
  https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
  sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vault terraform

La sortie attendue indique les versions Vault 1.20+ et Terraform 1.10+. Vérifiez avec vault version et terraform version. Si vous obtenez un binaire plus ancien, le dépôt apt n’est pas activé correctement.

Étape 2 : démarrer Vault en mode dev pour les tests

Le mode dev de Vault tourne en mémoire et déchiffre automatiquement le coffre — parfait pour valider l’intégration avant de passer en production. À ne JAMAIS utiliser pour des secrets réels.

# Lancer Vault en mode dev sur le port 8200
vault server -dev -dev-root-token-id="root-dev-token"
# Dans un autre terminal :
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='root-dev-token'
vault status

La commande vault status doit afficher Sealed: false et Initialized: true. C’est le signal que Vault accepte les requêtes API et que vous pouvez écrire des secrets.

Étape 3 : activer le moteur de secrets KV v2

Le moteur KV v2 versionne automatiquement les secrets et permet le rollback. C’est le moteur standard pour stocker mots de passe, clés API, certificats utilisés par Terraform.

# Activer KV v2 sur le path "secret"
vault secrets enable -version=2 -path=secret kv
# Stocker un secret pour Terraform
vault kv put secret/aws \
  access_key="AKIA..." \
  secret_key="abcd1234..."
# Vérifier
vault kv get secret/aws

La sortie liste la version courante (1) et les métadonnées. Toute modification crée une nouvelle version consultable avec vault kv get -version=N. Idéal pour auditer les rotations de clés.

Étape 4 : créer une politique Vault dédiée à Terraform

Le principe du moindre privilège impose une politique restreinte : Terraform ne doit lire que les secrets nécessaires à son module, jamais le coffre entier. Une fuite de token Terraform serait alors bornée.

# terraform-policy.hcl
path "secret/data/aws" {
  capabilities = ["read"]
}
path "secret/data/database/*" {
  capabilities = ["read", "list"]
}
# Charger la politique
vault policy write terraform terraform-policy.hcl

Vérifiez avec vault policy read terraform. La politique est désormais disponible mais pas encore associée à un token — c’est l’étape suivante.

Étape 5 : générer un token Vault scopé pour Terraform

Plutôt que d’utiliser le root token (qui ouvre tout le coffre), créez un token attaché à la politique terraform avec une TTL courte. Pour une CI tournant à Dakar ou Lomé, 1 heure suffit largement.

# Créer un token Terraform avec TTL 1 h
vault token create -policy=terraform -ttl=1h -renewable=true
# Sortie : token "hvs.CAES..."
export VAULT_TOKEN_TF="hvs.CAES..."

La TTL renouvelable permet à Terraform de prolonger sa session tant que le job CI tourne. Au-delà, le token expire automatiquement — un attaquant qui le récupèrerait dans les logs n’aurait qu’une fenêtre limitée.

Étape 6 : configurer le provider Vault dans Terraform

Terraform consomme les secrets Vault via le provider officiel hashicorp/vault. La déclaration se fait dans le bloc terraform et permet ensuite d’utiliser data "vault_kv_secret_v2" partout dans la stack.

# main.tf
terraform {
  required_providers {
    vault = {
      source  = "hashicorp/vault"
      version = "~> 4.4"
    }
  }
}
provider "vault" {
  address = "http://127.0.0.1:8200"
}
data "vault_kv_secret_v2" "aws" {
  mount = "secret"
  name  = "aws"
}

Lancez terraform init ; le plugin Vault est téléchargé dans .terraform/providers/. La donnée data.vault_kv_secret_v2.aws.data["access_key"] est désormais utilisable comme variable d’entrée pour le provider AWS ou Hetzner.

Étape 7 : injecter les secrets dans un provider AWS ou Hetzner

Concrètement, on récupère access_key et secret_key depuis Vault puis on les passe au provider cloud. Aucun secret n’apparaît jamais dans le code Terraform versionné — c’est l’objectif principal.

# providers.tf
provider "aws" {
  region     = "eu-west-3"
  access_key = data.vault_kv_secret_v2.aws.data["access_key"]
  secret_key = data.vault_kv_secret_v2.aws.data["secret_key"]
}
# Variante Hetzner Cloud
provider "hcloud" {
  token = data.vault_kv_secret_v2.aws.data["hcloud_token"]
}

Lors d’un terraform plan, les secrets restent en mémoire vive. Activez TF_LOG=DEBUG uniquement en local — ne jamais activer en CI sinon les secrets fuitent dans les logs GitLab ou GitHub Actions.

Étape 8 : authentification AppRole pour les pipelines CI/CD

Un token statique convient à un poste de dev, pas à une CI partagée. Vault propose AppRole : un couple role_id + secret_id rotatif, idéal pour GitLab CI ou GitHub Actions hébergés à Dakar.

# Activer AppRole et créer le rôle
vault auth enable approle
vault write auth/approle/role/terraform \
  token_policies="terraform" \
  token_ttl=1h secret_id_ttl=24h
# Récupérer les identifiants
vault read auth/approle/role/terraform/role-id
vault write -f auth/approle/role/terraform/secret-id

Le role_id est statique et peut être stocké en variable CI ; le secret_id est rotatif et injecté via un secret CI court. Cette dissociation limite l’impact d’une fuite — un attaquant doit récupérer les deux pour s’authentifier.

Étape 9 : tester l’intégration de bout en bout

Validez que Terraform récupère bien le secret puis crée la ressource cloud. Pour le test, déployez un simple groupe de sécurité AWS ou un serveur Hetzner CX23 (4,90 EUR/mois, soit 3 215 FCFA).

# Pipeline complet de test
terraform init
terraform plan -out=tfplan
terraform apply tfplan
# Vérifier que la ressource existe
aws ec2 describe-security-groups --group-names test-vault
# Détruire pour ne pas générer de facture
terraform destroy -auto-approve

Le serveur démarre en 30 à 45 secondes ; la facturation Hetzner est à l’heure entamée donc un test complet coûte 0,007 EUR (4,6 FCFA). Toujours détruire après le test pour éviter la facturation continue.

Étape 10 : passer en production avec Vault HA et auto-unseal

Pour la production, abandonnez le mode dev. Déployez Vault en cluster 3 nœuds avec backend Raft intégré et auto-unseal via une clé KMS chez Hetzner ou AWS. C’est la configuration recommandée par HashiCorp depuis Vault 1.13.

# Extrait config Vault HA (vault.hcl)
storage "raft" {
  path    = "/opt/vault/data"
  node_id = "vault-fsn-1"
}
listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_cert_file = "/etc/vault/cert.pem"
  tls_key_file  = "/etc/vault/key.pem"
}
seal "awskms" {
  region     = "eu-west-3"
  kms_key_id = "alias/vault-unseal"
}

Le cluster Raft tolère la perte d’un nœud sans interruption. L’auto-unseal supprime l’étape manuelle de saisie des clés Shamir au démarrage — indispensable si vos serveurs redémarrent automatiquement après une coupure de courant à Dakar ou Abidjan.

Pour explorer plus loin, consultez notre tutoriel Terraform sur Hetzner Cloud et le guide gestion des secrets en équipe DevOps.

Étape 11 : auditer les accès Vault et alerter en cas d’anomalie

Activez l’audit log Vault dès le premier déploiement. Chaque requête API est tracée avec horodatage, identité et chemin demandé. Indispensable pour un audit ANSI ou un client final exigeant la conformité ISO 27001.

# Activer audit log fichier
vault audit enable file file_path=/var/log/vault/audit.log
# Lister les audits actifs
vault audit list
# Exemple de ligne JSON dans l'audit log
{"time":"2026-05-05T08:42:17Z","type":"request",
 "auth":{"client_token_accessor":"abc","display_name":"approle"},
 "request":{"path":"secret/data/aws","operation":"read"}}

Couplez ces logs à un SIEM (Wazuh, Loki+Grafana) pour déclencher une alerte sur tout accès en dehors des heures ouvrées. Un accès à 03h30 GMT à un secret de production est suspect même depuis un runner CI.

Étape 12 : rotation automatique des secrets dynamiques

Au-delà du KV statique, Vault génère des secrets éphémères pour PostgreSQL, MySQL ou AWS IAM. Terraform récupère un identifiant valable 1 heure puis Vault le révoque automatiquement — la fuite éventuelle expire seule.

# Activer le moteur database PostgreSQL
vault secrets enable database
vault write database/config/postgres-prod \
  plugin_name=postgresql-database-plugin \
  connection_url="postgresql://{{username}}:{{password}}@db:5432/app" \
  allowed_roles="readonly"
vault write database/roles/readonly \
  db_name=postgres-prod \
  default_ttl="1h" max_ttl="24h"

Terraform appelle ensuite data "vault_database_secret_backend_static_credentials" et reçoit un user/password fraîchement créé. À la fin du plan, Vault révoque le compte automatiquement — votre base de données ne contient plus aucun identifiant orphelin.

مشاركة