Aller au contenu
Infrastructure as Code medium

Vault-id multiples : isoler dev, staging et prod avec des mots de passe distincts

12 min de lecture

Logo Ansible

Un mot de passe vault unique partagé entre dev et prod est un risque grave : un développeur qui doit lire un secret de dev obtient de fait l’accès aux secrets de prod. Ansible résout ce problème depuis la version 2.4 avec la notion de vault-id : chaque fichier chiffré porte un label (dev, prod, staging) et utilise son propre mot de passe. Cette page montre comment chiffrer, déchiffrer et rotater les secrets par environnement, sans toucher aux autres.

À la fin, vous saurez isoler les environnements, lancer un playbook qui mixe plusieurs vault-ids dans la même exécution, et rotater le mot de passe prod sans toucher à dev.

  • Format --vault-id <label>@<source> et différence avec --vault-password-file.
  • Header $ANSIBLE_VAULT;1.2;AES256;dev vs 1.1;AES256 (sans label).
  • Chiffrer un fichier avec un label spécifique.
  • Déchiffrer automatiquement quand plusieurs vault-ids sont fournis.
  • Rotater un seul environnement sans toucher aux autres.
  • Sécuriser les fichiers de mot de passe en CI/CD selon l’environnement cible.
  • Avoir lu Introduction à Ansible Vault.
  • Comprendre le pattern group_vars/<env>/ par environnement.
  • Ansible 2.4+ (le mécanisme vault-id existe depuis cette version).

Trois raisons concrètes motivent l’isolation par vault-id.

Limite du périmètre humain : un dev qui contribue au playbook dev n’a aucune raison de pouvoir lire le secret prod. Avec un mot de passe unique, il l’obtient mécaniquement dès qu’il a accès au repo. Avec deux vault-ids, on lui transmet uniquement le mot de passe dev.

Rotation indépendante : compromission suspectée du mot de passe dev (laptop volé d’un dev junior) ? On rote uniquement les fichiers dev/, on ne touche pas à prod. Sans vault-id, il fallait tout rechiffrer en urgence.

Audit et compliance : la séparation des environnements est exigée par la plupart des référentiels (PCI-DSS, ISO 27001). Un audit voit immédiatement que prod est protégé par un secret distinct, non dérivable du dev.

Le format général :

--vault-id <label>@<source>
  • <label> : nom symbolique (dev, staging, prod). Inscrit dans l’en-tête du fichier chiffré pour qu’Ansible sache quel mot de passe utiliser.
  • <source> : où Ansible récupère le mot de passe.
    • @prompt : demande interactivement.
    • @<chemin> : lit un fichier (mode 0600).
    • @<script> : exécute un script qui retourne le mot de passe sur stdout (utile pour intégrer un secret manager).

Exemples concrets :

Fenêtre de terminal
# Demander interactivement le mot de passe dev
ansible-vault encrypt secret.yml --vault-id dev@prompt
# Lire le mot de passe depuis un fichier
ansible-vault encrypt secret.yml --vault-id prod@.vault_password_prod
# Récupérer dynamiquement depuis un script
ansible-vault encrypt secret.yml --vault-id prod@./get_prod_password.sh
FormatHeaderCe qu’il contient
1.1$ANSIBLE_VAULT;1.1;AES256Sans label. Ansible essaie tous les vault-ids fournis jusqu’à ce qu’un fonctionne.
1.2$ANSIBLE_VAULT;1.2;AES256;<label>Avec label. Ansible utilise directement le bon mot de passe.

Le format 1.2 est strictement supérieur : plus rapide (pas d’essais successifs), permet le debug (Decryption failed for label 'dev' plutôt qu’une erreur opaque), et lisible à l’œil nu (head -1 montre le label).

Format 1.2 s’active automatiquement dès qu’on chiffre avec --vault-id <label>@<source>.

Étape 1 — Préparer les fichiers de mot de passe

Section intitulée « Étape 1 — Préparer les fichiers de mot de passe »

Un fichier par environnement, mode 0600, gitignored.

Fenêtre de terminal
cd labs/vault/id-multiples/
# Mots de passe distincts par env
echo "DevPasswordLab79" > .vault_password_dev
echo "ProdPasswordLab79Strong!" > .vault_password_prod
chmod 600 .vault_password_dev .vault_password_prod
# Bloquer les commits accidentels
echo ".vault_password_*" >> ../../.gitignore

Pourquoi deux fichiers plutôt qu’un seul mot de passe à prompt ? Les fichiers permettent un ansible.cfg ou un script automatisé qui n’attend pas d’input interactif — pratique en CI/CD.

Fenêtre de terminal
# Préparer le secret dev
cat > inventory/group_vars/dev/secrets.yml <<'EOF'
db_password: "DevDbPassword123"
api_token: "dev_token_xyz"
EOF
# Chiffrer avec le label "dev"
ansible-vault encrypt inventory/group_vars/dev/secrets.yml \
--vault-id dev@.vault_password_dev
# Idem pour prod
cat > inventory/group_vars/prod/secrets.yml <<'EOF'
db_password: "ProdDbPasswordSuperStrong!"
api_token: "prod_token_critical_2026"
EOF
ansible-vault encrypt inventory/group_vars/prod/secrets.yml \
--vault-id prod@.vault_password_prod

Vérifier les en-têtes :

Fenêtre de terminal
head -1 inventory/group_vars/dev/secrets.yml
# → $ANSIBLE_VAULT;1.2;AES256;dev
head -1 inventory/group_vars/prod/secrets.yml
# → $ANSIBLE_VAULT;1.2;AES256;prod

Le label dans l’en-tête est la clé qui permettra à Ansible de router vers le bon mot de passe à l’exécution.

Étape 3 — Lancer le playbook avec plusieurs vault-ids

Section intitulée « Étape 3 — Lancer le playbook avec plusieurs vault-ids »

On fournit tous les vault-ids susceptibles d’être rencontrés. Ansible utilise le bon selon le label de chaque fichier.

Fenêtre de terminal
ansible-playbook -i inventory/hosts.yml \
--vault-id dev@.vault_password_dev \
--vault-id prod@.vault_password_prod \
playbook.yml

Si le playbook ne touche qu’à dev (filtre par groupe), seul le mot de passe dev est utilisé en pratique — mais Ansible n’aurait pas pu deviner sans avoir l’autre disponible au cas où.

Le test décisif : un mot de passe dev ne doit PAS pouvoir déchiffrer prod.

Fenêtre de terminal
# Tenter de déchiffrer prod avec le mot de passe dev
ansible-vault view inventory/group_vars/prod/secrets.yml \
--vault-id dev@.vault_password_dev

Sortie attendue :

ERROR! Decryption failed (no vault secrets were found that could decrypt) on inventory/group_vars/prod/secrets.yml

C’est le comportement souhaité : la séparation est étanche.

Suspicion de fuite du mot de passe dev ? On rote uniquement les fichiers labellisés dev.

Fenêtre de terminal
# Générer le nouveau mot de passe
echo "DevPassword2026Q2NewRotation" > .vault_password_dev_new
chmod 600 .vault_password_dev_new
# Rekey (ne change pas le contenu, juste le mot de passe)
ansible-vault rekey inventory/group_vars/dev/secrets.yml \
--vault-id dev@.vault_password_dev \
--new-vault-id dev@.vault_password_dev_new
# Remplacer l'ancien fichier
mv .vault_password_dev_new .vault_password_dev

Les fichiers prod/ ne sont pas touchés. Aucun runtime prod à redémarrer, aucun rechiffrement massif. C’est l’avantage clé du modèle vault-id.

En pipeline, chaque job ne reçoit que le mot de passe correspondant à son environnement.

# .gitlab-ci.yml (extrait)
deploy_dev:
stage: deploy
variables:
VAULT_PASSWORD_DEV: $VAULT_DEV_PASSWORD # ← GitLab CI Variables
script:
- echo "$VAULT_PASSWORD_DEV" > .vault_password_dev
- chmod 600 .vault_password_dev
- ansible-playbook -i inventory/hosts.yml \
--vault-id dev@.vault_password_dev \
--limit dev \
playbook.yml
only: [dev]
deploy_prod:
stage: deploy
variables:
VAULT_PASSWORD_PROD: $VAULT_PROD_PASSWORD
script:
- echo "$VAULT_PASSWORD_PROD" > .vault_password_prod
- chmod 600 .vault_password_prod
- ansible-playbook -i inventory/hosts.yml \
--vault-id prod@.vault_password_prod \
--limit prod \
playbook.yml
only: [main]
environment: production # ← protection environment GitLab

Bénéfices : un job dev compromis (PR malveillante, runner partagé) ne peut jamais déchiffrer prod, faute du mot de passe correspondant.

Le lab vault/id-multiples du repo ansible-training reproduit ce parcours avec 5 tests pytest qui valident :

  • Les en-têtes $ANSIBLE_VAULT;1.2;AES256;dev et ;prod sont bien présents.
  • Le mot de passe dev ne déchiffre pas prod (test d’isolation).
  • Le playbook utilise les bonnes variables selon le groupe.
  • Un challenge demande d’ajouter un troisième environnement staging.

Suivre : labs/vault/id-multiples/README.md.

  • Oubli du --vault-id : sans label, Ansible utilise format 1.1 et tente tous les mots de passe. Plus lent, et le contrat d’isolation s’effrite.
  • Même mot de passe sur deux labels : techniquement possible, mais casse l’argument sécurité. Garder des mots de passe distincts.
  • Confusion --vault-password-file vs --vault-id : le premier est l’ancienne syntaxe (un seul mot de passe). Le second est la version moderne (plusieurs labels possibles).
  • Label dans le nom du fichier .vault_password_<env> : convention pratique, mais le label vit dans l’en-tête du fichier chiffré, pas dans le nom du fichier de mot de passe.
  • --vault-id <label>@<source> lie un label à un mot de passe ou un script.
  • Le label est inscrit dans l’en-tête ($ANSIBLE_VAULT;1.2;AES256;<label>).
  • Un mot de passe par environnement isole les compromissions et permet la rotation indépendante.
  • En CI/CD, chaque job reçoit uniquement le mot de passe de son environnement cible.
  • La séparation est étanche : un mot de passe dev ne déchiffre pas un fichier prod.
  • Format 1.2 (avec label) est strictement supérieur à 1.1 (sans label) — toujours préférer --vault-id.

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn