Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 913 minIntermédiaire

Ansible Vault : chiffrer les secrets

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • chiffrer un fichier de variables ou une seule valeur ;
  • fournir le mot de passe du coffre sans l'écrire dans le dépôt ;
  • organiser vars.yml et vault.yml pour garder des variables lisibles ;
  • empêcher un secret d'apparaître dans la sortie avec no_log.

3 exercices corrigés

Ansible Vault est l'outil intégré à Ansible qui chiffre les données sensibles (mots de passe, jetons d'API, clés privées) avec AES-256, pour qu'elles puissent être rangées dans le dépôt Git avec le reste du projet sans être lisibles. Ce chapitre montre comment chiffrer un fichier ou une seule valeur, fournir le mot de passe du coffre, organiser les variables secrètes et empêcher un secret d'apparaître dans la sortie d'Ansible.

Le problème des secrets

Pour gérer les serveurs Windows, Ansible a besoin du mot de passe du compte de service svc-ansible. Pour les switchs, de celui du compte ansible. Pour Proxmox, d'un jeton d'API. Écrits en clair dans group_vars, ces secrets finissent dans Git : quiconque lit le dépôt (un stagiaire, un prestataire, une sauvegarde mal protégée, un dépôt publié par erreur) obtient les clés de l'infrastructure. Et un secret poussé une fois dans l'historique y reste, même effacé du fichier ensuite (cours Git, le fichier .gitignore et les secrets).

Ansible Vault chiffre ces valeurs. Le dépôt ne contient que du texte chiffré ; Ansible le déchiffre en mémoire, à l'exécution, avec un mot de passe de coffre (vault password) qui, lui, ne va jamais dans le dépôt.

Chiffrer un fichier

La commande ansible-vault gère les fichiers chiffrés :

bash
# Créer un fichier chiffré (ouvre l'éditeur défini par $EDITOR)
ansible-vault create inventaire/group_vars/windows/vault.yml

# Chiffrer un fichier existant
ansible-vault encrypt inventaire/group_vars/windows/vault.yml

# Le lire, le modifier (il est rechiffré à l'enregistrement)
ansible-vault view inventaire/group_vars/windows/vault.yml
ansible-vault edit inventaire/group_vars/windows/vault.yml

# Changer le mot de passe du coffre
ansible-vault rekey inventaire/group_vars/windows/vault.yml

# Le déchiffrer définitivement (à éviter)
ansible-vault decrypt inventaire/group_vars/windows/vault.yml

Chaque commande demande le mot de passe du coffre. Un fichier chiffré ressemble à ceci :

text
$ANSIBLE_VAULT;1.1;AES256
63646565366334313066666536306139386265323362336437663034303830363032313930623631
3631653764613639326138363862633339383663666634340a353138643735623430666233393863
…

La première ligne dit qu'il s'agit d'un coffre, au format 1.1, chiffré en AES-256. Le contenu est illisible, mais le fichier reste versionnable : Git voit qu'il a changé, pas ce qui a changé.

L'organisation vars.yml et vault.yml

Si tout le fichier de variables est chiffré, plus personne ne sait quelles variables il contient sans le déchiffrer, et grep ne trouve plus rien. La bonne pratique sépare chaque groupe en deux fichiers, dans un dossier au nom du groupe :

text
inventaire/group_vars/windows/
├── vars.yml     en clair : toutes les variables, dont certaines pointent vers le coffre
└── vault.yml    chiffré : seulement les secrets, préfixés par vault_

vault.yml, avant chiffrement :

yaml
---
vault_mdp_svc_ansible: "Mdp-Svc-Ansible-2026!"

vars.yml, en clair :

yaml
---
ansible_connection: winrm
ansible_port: 5986
ansible_winrm_transport: kerberos
ansible_user: svc-ansible@AD.SORBIER.EXAMPLE
ansible_password: "{{ vault_mdp_svc_ansible }}"

On lit vars.yml et on voit immédiatement que le mot de passe vient du coffre, sous le nom vault_mdp_svc_ansible. Ansible charge les deux fichiers du dossier pour tous les hôtes du groupe windows.

Chiffrer une seule valeur : encrypt_string

Pour un ou deux secrets, on peut aussi ne chiffrer que la valeur, au milieu d'un fichier en clair :

bash
ansible-vault encrypt_string --name vault_token_proxmox 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
text
vault_token_proxmox: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          65643362353466336234333333653638656562623462363331396662376435396332313233323665
          3436373530393135333663356331633466653937313862610a646365323930663332376565336334
          61343133353937366138623332323766623266643331613532653533666230316530633432346335
          6433393038306364320a346437333465343938613738383033336365626161656463356664376239
          39376262386330646466376331346139356138303032313230333366616666383966623733366633
          6432323465663063346638313162303030373737346465356236

Tu colles ce bloc tel quel dans un fichier de variables. L'étiquette YAML !vault dit à Ansible de déchiffrer la valeur à l'utilisation.

Fichier entièrement chiffréValeur chiffrée (encrypt_string)
LisibilitéOn ne voit pas les noms des variables (d'où le duo vars.yml et vault.yml)Le nom est en clair, seule la valeur est chiffrée
Modificationansible-vault editRechiffrer la valeur et remplacer le bloc
Revue dans GitLe fichier entier apparaît modifiéOn voit quelle variable a changé

Fournir le mot de passe du coffre

Trois façons, du plus simple au plus pratique :

bash
# 1. Le taper à chaque exécution
ansible-playbook site.yml --ask-vault-pass

# 2. Le lire dans un fichier, hors du dépôt, lisible par toi seul
ansible-playbook site.yml --vault-password-file ~/.config/ansible/coffre-sorbier.txt

# 3. Le déclarer dans ansible.cfg, une fois pour toutes
#    [defaults]
#    vault_password_file = ~/.config/ansible/coffre-sorbier.txt

Le fichier de mot de passe contient le mot de passe sur une ligne. Il doit être protégé (chmod 600), en dehors du dossier du projet, et ne jamais être commité. Sans mot de passe, Ansible s'arrête dès qu'il rencontre un coffre :

text
[ERROR]: Attempting to decrypt but no vault secrets found.

Le « fichier » de mot de passe peut aussi être un script exécutable qui affiche le mot de passe : il peut alors le lire dans un gestionnaire de secrets ou dans le trousseau du système, au lieu de le stocker en clair sur le disque.

Garder les secrets hors de la sortie

Chiffrer le dépôt ne suffit pas si le secret s'affiche ensuite dans la sortie d'Ansible, dans un journal ou dans l'historique d'un pipeline.

Le masquage automatique. Depuis ansible-core 2.22, Ansible remplace par $REDACTED$ les secrets qu'il connaît (valeurs issues d'un coffre, mots de passe de connexion) dans tout ce qu'il affiche. Une tâche maladroite qui affiche un mot de passe donne :

text
TASK [Afficher le secret (à ne jamais faire)] **********************************
ok: [localhost] => {
    "msg": "Le mot de passe est $REDACTED$"
}

La valeur reste utilisable par les modules : seul l'affichage est masqué.

no_log: true sur une tâche supprime toute sa sortie, arguments et résultat : à mettre sur chaque tâche qui manipule un secret que le masquage ne connaît pas (un mot de passe généré, une clé lue dans un fichier, un résultat d'API).

yaml
    - name: Définir le mot de passe du compte de sauvegarde
      ansible.builtin.user:
        name: sauvegarde
        password: "{{ vault_mdp_sauvegarde | password_hash('sha512', 'Sorbier2026sel', rounds=656000) }}"
      no_log: true

Et en dépannage, -vvv affiche beaucoup de détails, dont des arguments de modules : ne colle jamais une sortie verbeuse dans un ticket ou un forum sans la relire.

Les limites de Vault et les alternatives

Ansible Vault est simple et suffit pour une PME, mais il a des limites :

  • un mot de passe partagé : tous ceux qui l'ont lisent tous les secrets du coffre ; quand quelqu'un quitte l'équipe, il faut changer le mot de passe et les secrets eux-mêmes, qu'il a pu lire ;
  • pas de traçabilité des lectures, pas de rotation automatique des secrets.

Les organisations plus grandes utilisent un gestionnaire de secrets centralisé, interrogé par Ansible à l'exécution : HashiCorp Vault ou son fork libre OpenBao (collection community.hashi_vault), CyberArk, le coffre d'un fournisseur de cloud. Le secret n'est alors plus du tout dans le dépôt, et chaque lecture est journalisée.

Exercices

Exercice 1 sur 3 Organiser les secrets des switchs Réussi À revoir

Le groupe switchs a besoin du mot de passe Mdp-Switchs-2026! du compte ansible. Écris le contenu des deux fichiers du dossier inventaire/group_vars/switchs/, puis les commandes pour chiffrer le bon fichier et vérifier son contenu.

Voir la réponseMasquer la réponse de l'exercice 1

inventaire/group_vars/switchs/vars.yml, en clair :

yaml
---
ansible_connection: ansible.netcommon.network_cli
ansible_network_os: cisco.ios.ios
ansible_user: ansible
ansible_password: "{{ vault_mdp_switchs }}"

inventaire/group_vars/switchs/vault.yml, avant chiffrement :

yaml
---
vault_mdp_switchs: "Mdp-Switchs-2026!"
bash
ansible-vault encrypt inventaire/group_vars/switchs/vault.yml
ansible-vault view inventaire/group_vars/switchs/vault.yml

Si l'ancien fichier group_vars/switchs.yml existe encore, supprime-le : un fichier et un dossier au même nom de groupe seraient chargés tous les deux, source de confusion. Mieux : crée directement le fichier avec ansible-vault create, pour que le secret ne soit jamais écrit en clair sur le disque.

Tu avais trouvé ?

Exercice 2 sur 3 Un départ dans l'équipe Réussi À revoir

Un alternant qui avait le mot de passe du coffre de production quitte Sorbier. Antoine propose de lancer ansible-vault rekey sur tous les fichiers vault.yml. Est-ce suffisant ? Que faut-il faire ?

Voir la réponseMasquer la réponse de l'exercice 2

Non. rekey change le mot de passe du coffre, ce qui empêche l'alternant de déchiffrer les futures versions des fichiers. Mais il a pu lire les secrets eux-mêmes, et il a peut-être une copie du dépôt, déchiffrable avec l'ancien mot de passe. Il faut :

  1. changer chaque secret à sa source : mot de passe de svc-ansible dans l'Active Directory, mot de passe du compte des switchs, nouveau jeton d'API Proxmox (et révocation de l'ancien) ;
  2. mettre les nouvelles valeurs dans les coffres (ansible-vault edit) ;
  3. faire le rekey avec un nouveau mot de passe, transmis seulement aux personnes restantes ;
  4. désactiver ses comptes nominatifs (bastion, Git, annuaire) et retirer sa clé de socle_cles_ansible, ce qu'Ansible propage à tout le parc au passage suivant.

Tu avais trouvé ?

Exercice 3 sur 3 Le secret qui s'affiche Réussi À revoir

Moussa a écrit cette tâche pour créer un compte local sur les serveurs. Que voit-on dans la sortie, et que proposes-tu ?

yaml
    - name: Créer le compte de dépannage
      ansible.builtin.user:
        name: depannage
        password: "{{ lookup('ansible.builtin.password', '/dev/null', length=20) | password_hash('sha512') }}"
Voir la réponseMasquer la réponse de l'exercice 3

Trois problèmes. Le mot de passe est généré par le lookup password, pas lu dans un coffre : le masquage automatique ne le connaît pas, et le hachage peut apparaître dans la sortie en mode verbeux ou avec --diff. Avec /dev/null comme fichier, le mot de passe n'est enregistré nulle part : personne ne le connaît, donc le compte est inutilisable pour un dépannage. Enfin, un nouveau mot de passe et un nouveau sel à chaque exécution : la tâche est toujours changed.

Proposition : stocker le mot de passe dans le coffre (vault_mdp_depannage), le hacher avec un sel fixe propre à ce compte (ou utiliser update_password: on_create) et ajouter no_log: true à la tâche. Et se demander si un compte local partagé est vraiment nécessaire : un accès nominatif par clé est préférable.

Tu avais trouvé ?

Chapitre terminé !

Fais les 3 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Gérer Windows Server avec Ansible (WinRM, SSH)Revoir le sommaire du cours