Aller au contenu
Infrastructure as Code medium

Lire des secrets Vault depuis Terraform sans les figer dans le state

6 min de lecture

logo terraform

L'examen Terraform Professional cite nommément Vault au sous-objectif 2f. Le problème n'est pas de lire un secret Vault : c'est de le lire sans qu'il finisse en clair dans le state. Car la façon la plus répandue de le faire, une data source, recopie la valeur dans terraform.tfstate, et sensitive_values la marque true sans rien cacher du tout.

Ce guide montre le piège, puis la bonne combinaison : une lecture éphémère et une écriture write-only, pour qu'un secret externe transite de Vault jusqu'à son destinataire sans laisser de trace côté Terraform. Tous les exemples ont été exécutés sur Terraform v1.15.4 avec le provider hashicorp/vault en 5.x, contre un serveur vault server -dev.

  • Le piège : pourquoi la data source vault_kv_secret_v2 fait fuiter le secret
  • La lecture éphémère : le bloc ephemeral "vault_kv_secret_v2"
  • L'écriture write-only : data_json_wo et son argument de version
  • Le duo éphémère + write-only, de bout en bout sans trace
  • La rotation : piloter le renvoi par un entier de version
  • Terraform 1.11 ou plus récent (installer Terraform) : les ressources éphémères et les arguments write-only l'exigent.
  • Un serveur Vault : vault server -dev suffit, en mémoire, descellé, avec un jeton racine. Vault Community Edition est libre et gratuit.
  • Les valeurs éphémères et les arguments write-only (valeurs éphémères, write-only).

Le piège : la data source recopie le secret en clair

Section intitulée « Le piège : la data source recopie le secret en clair »

La voie historique pour lire un secret KV v2 est une data source :

data "vault_kv_secret_v2" "source" {
mount = "kvv2"
name = "app/db"
}

Elle fonctionne, mais elle recopie la valeur dans le state. Le provider émet d'ailleurs un avertissement de dépréciation sur cette data source.

La lecture éphémère : ephemeral "vault_kv_secret_v2"

Section intitulée « La lecture éphémère : ephemeral "vault_kv_secret_v2" »

Le provider hashicorp/vault en 5.x expose la même lecture sous forme éphémère. Un bloc ephemeral produit une valeur disponible pendant l'opération, mais jamais écrite dans le state ni le plan :

ephemeral "vault_kv_secret_v2" "source" {
mount = "kvv2"
name = "app/db"
}

On référence son résultat par ephemeral.vault_kv_secret_v2.source.data["password"]. Cette valeur ne peut aller que dans un contexte éphémère : une configuration de provider, un provisioner, ou un argument write-only. C'est ce dernier qui complète la chaîne.

La ressource vault_kv_secret_v2 a deux façons d'écrire son contenu :

ArgumentPersisté dans le state ?
data_json (ordinaire)oui (marqué sensible, mais présent)
data_json_wo (write-only)non, jamais

L'argument write-only forme un couple obligatoire avec un numéro de version :

resource "vault_kv_secret_v2" "cible" {
mount = "kvv2"
name = "app/copie"
data_json_wo = jsonencode({ password = ephemeral.vault_kv_secret_v2.source.data["password"] })
data_json_wo_version = 1
}

Après l'apply, dans terraform show -json : data_json_wo vaut null, data_json vaut null, data est un objet vide ; seul data_json_wo_version subsiste, avec un nombre bien réel.

Bout à bout, le secret ne touche jamais le disque côté Terraform : lu par un ephemeral (pas de state), écrit par un data_json_wo (pas de state). Il transite en mémoire pendant l'opération, du KV source vers le KV cible. C'est la réponse complète au sous-objectif 2f, et la seule qui ne laisse aucune trace, ni en clair ni sous forme dérivée.

Comme tout write-only, data_json_wo n'est renvoyé au provider que lorsque son numéro de version change. Conséquence directe, vérifiée à l'exécution :

  • changer le secret dans le KV source sans toucher data_json_wo_version ne produit aucun plan : Terraform ne suit pas ce qu'il ne stocke pas ;
  • porter la version de 1 à 2 produit un plan, et l'apply pousse la nouvelle valeur dans la cible, dont la métadonnée KV passe à la version 2.

C'est le mécanisme de rotation : on incrémente un entier, jamais on ne manipule le secret en clair dans la configuration.

  • La data source vault_kv_secret_v2 fuit le secret dans le state (et est dépréciée) ; sensitive n'y change rien.
  • Le bloc ephemeral "vault_kv_secret_v2" lit sans persister ; sa valeur ne va que dans un contexte éphémère.
  • data_json_wo écrit sans persister ; data_json_wo, data_json valent null et data est vide dans le state.
  • Seul data_json_wo_version subsiste et pilote la rotation : sans son incrément, un nouveau secret source est ignoré.
  • Le duo éphémère + write-only ne laisse aucune trace côté Terraform.

Les questions ci-dessous portent sur les points qui bloquent le plus souvent : la data source qui fuit, la façon de lire sans persister, et pourquoi un secret changé côté Vault n'est pas repris. Chaque réponse donne la vérification correspondante.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn