ITSkillsCenter
Blog

Gérer les secrets avec Ansible Vault pas à pas

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

📍 Article principal : Ansible 2026 : la stack pratique pour automatiser Linux et Windows

Ce tutoriel suppose que vous savez déjà lancer un playbook et que vos rôles sont structurés proprement. On attaque maintenant les secrets — la couche que personne ne peut éviter en production.

Ce que vous aurez à la fin

Une chaîne complète de gestion des secrets Ansible : chiffrement de fichiers entiers, chiffrement de variables individuelles, gestion de plusieurs clés via vault-id, stockage de la passphrase ailleurs que dans Git, et exécution dans un pipeline GitHub Actions sans jamais exposer le secret. À chaque étape, on prouve que la donnée sensible reste illisible pour quiconque n’a pas la clé.

Prérequis

  • ansible-core 2.20 ou supérieur installé.
  • Un projet Ansible existant avec au moins un fichier group_vars/.
  • Un dépôt Git initialisé (même local) — c’est dans Git que les fichiers vault vivent.
  • Niveau attendu : avoir lu une fois la documentation officielle Vault ; pas besoin d’avoir tout retenu.
  • Temps : 60 à 90 minutes en lecture active.

Étape 1 — Comprendre ce que Vault chiffre, et ce qu’il ne chiffre pas

Avant la première commande, fixons les attentes. Ansible Vault chiffre des fichiers ou des variables, pas des conversations réseau. Quand un playbook tourne, Ansible déchiffre les variables en mémoire sur le contrôleur, les utilise pour rendre des gabarits ou les passer à des modules, puis les transmet aux cibles via SSH. Le tunnel SSH protège la transmission, Vault protège le stockage. Les deux sont indépendants — l’un sans l’autre laisse une faille.

L’algorithme de chiffrement utilisé est AES-256 en mode CTR avec dérivation de clé via PBKDF2-HMAC-SHA256 (10 000 itérations dans le format 1.1, qui est le format produit par défaut depuis longtemps par ansible-vault encrypt). Concrètement, vous fournissez une passphrase, Ansible en dérive une clé symétrique, le contenu est chiffré. Sans la passphrase, on ne lit rien — pas de cassage faisable dans des temps humains tant que la passphrase est forte.

La conséquence pratique : la passphrase est le seul secret réel. Si elle fuite, tous les fichiers chiffrés deviennent lisibles. Si elle est faible (un mot du dictionnaire), un attaquant peut la deviner par force brute hors-ligne. La règle d’or : une passphrase générée aléatoirement, longue, et stockée hors du dépôt Git.

Étape 2 — Le premier fichier chiffré

On commence par le cas le plus simple : un fichier YAML entier qui contient des secrets. Imaginons une clé d’API pour un fournisseur cloud, qu’on veut stocker dans group_vars/all/secrets.yml.

On crée le fichier en clair une première fois pour comprendre la structure, puis on le chiffre :

mkdir -p group_vars/all
cat > group_vars/all/secrets.yml <<'EOF'
hcloud_api_token: "abc123def456ghi789"
backup_s3_access_key: "AKIAEXAMPLE"
backup_s3_secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
EOF

Avant de chiffrer, on génère une passphrase aléatoire forte. Ne pas inventer la passphrase soi-même — un humain produit toujours des entropies plus faibles qu’il ne le croit :

openssl rand -base64 32 > ~/.ansible/vault-pass-dev
chmod 600 ~/.ansible/vault-pass-dev

Cette commande génère 32 octets aléatoires depuis /dev/urandom et les encode en base64 — environ 44 caractères de passphrase, suffisant pour résister à la force brute hors-ligne. Le chmod 600 garantit que seul votre utilisateur la lit.

On chiffre le fichier :

ansible-vault encrypt group_vars/all/secrets.yml --vault-password-file ~/.ansible/vault-pass-dev

Le fichier est réécrit en place. Si vous l’ouvrez maintenant, vous verrez quelque chose comme $ANSIBLE_VAULT;1.1;AES256 suivi d’une longue chaîne hexadécimale. C’est ce qu’un commit Git va capturer — illisible, donc safe à pousser.

Pour vérifier que tout marche, on lit le fichier :

ansible-vault view group_vars/all/secrets.yml --vault-password-file ~/.ansible/vault-pass-dev

Le contenu original s’affiche, sans modifier le fichier sur disque. Pour éditer, on utilise ansible-vault edit qui ouvre $EDITOR sur une copie déchiffrée temporaire et re-chiffre à la fermeture.

Étape 3 — Variables individuelles avec encrypt_string

Chiffrer un fichier entier est pratique mais a un défaut : le diff Git devient inutile. Un changement d’un seul secret modifie tout le blob. Pour les projets à plusieurs développeurs, on préfère souvent chiffrer chaque variable individuellement, en gardant le reste du fichier YAML lisible.

La commande :

ansible-vault encrypt_string \
  --vault-password-file ~/.ansible/vault-pass-dev \
  --name 'hcloud_api_token' \
  'abc123def456ghi789'

Elle produit une sortie de la forme :

hcloud_api_token: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  3536323566306163653239616336353436366331333564653930376535343361373261346433
  3439393962623737386339386232613137323931326332370a323535393037656434323063
  ...

On colle ce bloc dans un group_vars/all/main.yml classique, à côté d’autres variables en clair :

app_name: "monapp"
app_port: 8080
hcloud_api_token: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  3536323566306163...

Le fichier reste lisible. Un diff Git montre quelles variables ont changé, sans révéler les valeurs sensibles. C’est le pattern moderne, à privilégier dès qu’une revue de code régulière est en place.

Étape 4 — Lancer un playbook avec un fichier vault

Au moment de l’exécution, Ansible doit savoir où trouver la passphrase. Trois options.

Option A — fichier de passphrase. On passe le drapeau --vault-password-file :

ansible-playbook -i inventory/hosts.yml playbooks/site.yml \
  --vault-password-file ~/.ansible/vault-pass-dev

C’est l’approche utilisée en CI où la passphrase est exposée comme un fichier temporaire injecté par le runner.

Option B — saisie interactive. Le drapeau --ask-vault-pass demande la passphrase au lancement. Acceptable pour un développeur en local qui ne veut pas la stocker, lourd pour des opérations répétées.

Option C — variable d’environnement. En définissant ANSIBLE_VAULT_PASSWORD_FILE=~/.ansible/vault-pass-dev dans son shell ou son direnv, on évite le drapeau à chaque commande. C’est l’option qu’on adopte pour confort en local sur un poste sécurisé.

Dans tous les cas, le fichier de passphrase ne doit JAMAIS entrer dans Git. Ajoutez-le immédiatement à .gitignore :

.vault-pass*
.vault-pass-*
*.vault.key

Étape 5 — Vault-id : plusieurs clés pour plusieurs environnements

Sur un projet sérieux, vous aurez vite besoin de séparer les secrets par environnement : la clé d’API de staging n’est pas celle de production, et vous ne voulez pas que tous les développeurs aient la passphrase de prod. C’est exactement ce que résout le mécanisme vault-id.

Un vault-id est un label associé à une passphrase. Quand vous chiffrez un fichier, vous lui attachez le label ; quand vous lancez un playbook, vous fournissez la liste des labels et de leurs sources. Ansible essaie chaque source jusqu’à trouver celle qui déchiffre.

On crée deux passphrases distinctes :

openssl rand -base64 32 > ~/.ansible/vault-pass-dev
openssl rand -base64 32 > ~/.ansible/vault-pass-prod
chmod 600 ~/.ansible/vault-pass-*

On chiffre group_vars/staging/secrets.yml avec le label dev :

ansible-vault encrypt group_vars/staging/secrets.yml \
  --vault-id dev@~/.ansible/vault-pass-dev

Et group_vars/production/secrets.yml avec le label prod :

ansible-vault encrypt group_vars/production/secrets.yml \
  --vault-id prod@~/.ansible/vault-pass-prod

Les fichiers chiffrés contiennent désormais le label dans leur en-tête :

$ANSIBLE_VAULT;1.2;AES256;prod
3536323566303039613263633535...

Au moment d’exécuter, on passe les deux sources en même temps :

ansible-playbook -i inventory/production playbooks/site.yml \
  --vault-id dev@~/.ansible/vault-pass-dev \
  --vault-id prod@~/.ansible/vault-pass-prod

Ansible utilise automatiquement la bonne passphrase pour chaque fichier. Un développeur qui n’a que le fichier vault-pass-dev peut lancer staging mais reçoit une erreur explicite sur production. C’est exactement ce qu’on veut.

Étape 6 — Stocker la passphrase ailleurs que sur le disque

Pour un poste personnel, un fichier ~/.ansible/vault-pass-dev protégé par chmod 600 est acceptable. Pour les rôles privilégiés (admin de prod, opérateur SRE), on veut éviter qu’une compromission du compte UNIX expose toutes les passphrases. Deux approches sont mûres en 2026.

Pass intégré au keyring système. Sur macOS, on utilise security find-generic-password ; sur Linux desktop, secret-tool ou libsecret via GNOME Keyring/KWallet. Un script appelé par --vault-password-file récupère la passphrase à la volée :

cat > ~/.ansible/vault-pass-prod.sh <<'EOF'
#!/usr/bin/env bash
secret-tool lookup ansible-vault prod
EOF
chmod 700 ~/.ansible/vault-pass-prod.sh

ansible-playbook ... --vault-password-file ~/.ansible/vault-pass-prod.sh

Ansible accepte un script exécutable comme password file : il l’exécute, lit stdout, utilise la sortie comme passphrase. C’est ce qui rend toutes ces intégrations possibles.

Gestionnaire de secrets externe. En entreprise, la passphrase de prod est stockée dans Vault HashiCorp, AWS Secrets Manager, Azure Key Vault ou équivalent. Le script récupère le secret via l’API du gestionnaire, authentifié par un mécanisme contextuel (rôle IAM AWS, identité gérée Azure, AppRole HashiCorp).

Étape 7 — Intégration GitHub Actions

Le scénario classique : le pipeline CI doit déployer en staging à chaque push sur main. La passphrase de staging est stockée comme secret du dépôt (Settings → Secrets and variables → Actions). Le workflow l’expose à Ansible le temps du job, sans jamais l’écrire en clair dans les logs.

name: Deploy staging
on:
  push:
    branches: [main]

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

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install ansible-core
        run: pip install ansible-core==2.20.* ansible-lint

      - name: Install collections and roles
        run: |
          ansible-galaxy collection install -r collections/requirements.yml
          ansible-galaxy role install -r roles/requirements.yml -p roles/

      - name: Write vault password to ephemeral file
        env:
          VAULT_PASS_DEV: ${{ secrets.ANSIBLE_VAULT_DEV }}
        run: |
          umask 077
          echo "$VAULT_PASS_DEV" > "$RUNNER_TEMP/vault.pass"

      - name: Run playbook
        env:
          ANSIBLE_HOST_KEY_CHECKING: 'False'
        run: |
          ansible-playbook -i inventory/staging playbooks/site.yml \
            --vault-id dev@"$RUNNER_TEMP/vault.pass"

Trois précautions importantes dans ce workflow. Première : la passphrase est écrite dans $RUNNER_TEMP, qui est nettoyé automatiquement à la fin du job. Deuxième : umask 077 avant l’écriture garantit que le fichier est en 600 dès sa création. Troisième : on ne fait jamais echo de la valeur du secret — GitHub Actions masque les secrets dans les logs, mais un echo dans un fichier déjà ouvert peut fuiter.

Étape 8 — Re-chiffrer après une compromission

Si une passphrase fuite (clé USB perdue, poste compromis, ancien employé qui en avait connaissance), il faut re-chiffrer tous les fichiers vault avec une nouvelle passphrase. La commande dédiée existe :

openssl rand -base64 32 > ~/.ansible/vault-pass-prod-v2
chmod 600 ~/.ansible/vault-pass-prod-v2

ansible-vault rekey \
  --new-vault-password-file ~/.ansible/vault-pass-prod-v2 \
  --vault-password-file ~/.ansible/vault-pass-prod \
  group_vars/production/secrets.yml

Le fichier est ré-chiffré en place avec la nouvelle clé. Vous remplacez ensuite l’ancien fichier de passphrase par le nouveau partout — keyring, secret CI, fichier local. La rotation prend quelques minutes si elle est planifiée. Elle prend des heures si elle est improvisée sous pression — d’où l’intérêt d’écrire la procédure une fois calmement.

Erreurs fréquentes

Erreur Cause Solution
Decryption failed Mauvaise passphrase ou mauvais vault-id Vérifier le label de l’en-tête du fichier ; passer toutes les sources possibles
Diff Git devient illisible après vault Chiffrement intégral du fichier au lieu de variables individuelles Préférer encrypt_string pour les valeurs ponctuelles
Passphrase committée par accident .vault-pass hors .gitignore Re-chiffrer avec une nouvelle clé, puis purger l’historique avec git filter-repo
Variable vault déchiffrée mais valeur fausse Espace ou retour à la ligne dans la passphrase du fichier Régénérer le fichier avec openssl rand sans echo manuel
CI retourne permission denied sur le fichier de passphrase umask non posé avant l’écriture Ajouter umask 077 dans le step

Tutoriels frères

Pour explorer plus loin

FAQ

Vault remplace-t-il un gestionnaire de secrets comme HashiCorp Vault ?
Non. Ansible Vault chiffre des fichiers statiques. HashiCorp Vault stocke et distribue des secrets dynamiquement, avec rotation, audit, et déchiffrement à la demande. Les deux outils se complètent : on stocke les secrets dans HashiCorp Vault, on récupère la passphrase Ansible Vault depuis HashiCorp Vault au moment du run.

Peut-on déchiffrer un fichier vault si on perd la passphrase ?
Non. Aucun mécanisme de récupération. C’est pour cette raison qu’on stocke la passphrase dans deux endroits indépendants — typiquement, le keyring du SRE principal et un coffre d’entreprise (1Password, Bitwarden) accessible aux secours.

Puis-je versionner les fichiers vault dans le même dépôt que le code ?
Oui, et c’est même la pratique courante. Les fichiers chiffrés sont des chaînes opaques — pousser sur GitHub public ne révèle rien tant que la passphrase reste secrète. Cela dit, n’écrivez jamais la passphrase dans un commentaire du fichier vault ou dans un README à côté.

Un développeur junior peut-il lancer le playbook de prod avec sa propre vault-id ?
Non — il n’aura pas la passphrase prod. C’est précisément l’intérêt du mécanisme vault-id. Les déploiements prod passent par CI ou par un opérateur senior, et la passphrase prod ne quitte jamais ces périmètres.

Le format 1.1 est-il toujours d’actualité ?
Oui pour la majorité des projets — c’est ce qu’encrypt produit par défaut. Le format 1.2 ajoute le label vault-id dans l’en-tête. Les deux sont supportés indéfiniment et coexistent dans un même projet.

Peut-on déchiffrer un fichier vault sans Ansible ?
Théoriquement oui — l’algorithme est documenté et il existe des implémentations Python tierces. En pratique on s’en abstient, parce que se priver de l’outil officiel ouvre des erreurs subtiles d’encodage.

Sponsoriser ce contenu

Cet emplacement est à vous

Position premium en fin d'article — c'est l'instant où les lecteurs sont le plus engagés. Réservez cet espace pour votre marque, votre formation ou votre offre.

Recevoir nos tarifs
Publicité