Introduction : Pourquoi Chiffrer vos Secrets ?
L'automatisation avec Ansible implique inévitablement la manipulation de données sensibles : mots de passe de bases de données, clés API, certificats SSL, tokens d'authentification, clés SSH privées. Ces secrets sont nécessaires pour que vos playbooks fonctionnent, mais les stocker en clair dans vos fichiers YAML est une faille de sécurité majeure.
Imaginez la situation suivante : votre fichier group_vars/all.yml contient le mot de passe root de votre base de données de production. Ce fichier est versionné dans Git. Toute personne ayant accès au dépôt — développeurs, stagiaires, prestataires — peut lire ce mot de passe. Pire encore, si le dépôt est public ou si une fuite se produit, vos secrets sont exposés au monde entier.
Architecture en un coup d'œil

Ansible Vault résout ce problème en fournissant un mécanisme de chiffrement intégré directement dans Ansible. Il permet de chiffrer des fichiers entiers ou des variables individuelles avec l'algorithme AES-256, un standard de chiffrement militaire. Les fichiers chiffrés peuvent être versionnés dans Git en toute sécurité : sans le mot de passe Vault, leur contenu est illisible.
Dans cet article, nous allons explorer en profondeur toutes les fonctionnalités d'Ansible Vault : création et édition de fichiers chiffrés, chiffrement de variables individuelles, gestion multi-vault, intégration CI/CD, et bonnes pratiques de sécurité. Vous apprendrez à protéger vos secrets sans compromettre l'ergonomie de votre workflow Ansible.
Les Commandes Fondamentales d'Ansible Vault
Ansible Vault s'utilise via la commande ansible-vault qui propose plusieurs sous-commandes. Voyons chacune d'entre elles en détail.
ansible-vault create : Créer un fichier chiffré
La commande create crée un nouveau fichier directement chiffré. Elle ouvre votre éditeur de texte par défaut (défini par la variable d'environnement $EDITOR) pour que vous saisissiez le contenu, puis le chiffre automatiquement à la sauvegarde :
# Créer un nouveau fichier chiffré
ansible-vault create group_vars/production/vault.yml
# Ansible vous demandera de saisir un mot de passe Vault :
# New Vault password:
# Confirm New Vault password:
# Votre éditeur s'ouvre. Saisissez le contenu :
# vault_db_password: "S3cur3P@ssw0rd!"
# vault_api_key: "ak_live_xxxxxxxxxxx"
# vault_ssl_passphrase: "M0nCert1f1cat!"
# Sauvegardez et quittez l'éditeur. Le fichier est automatiquement chiffré.Après la création, si vous ouvrez le fichier avec cat, vous verrez quelque chose comme ceci :
cat group_vars/production/vault.yml
# Résultat :
# $ANSIBLE_VAULT;1.1;AES256
# 33363965326261303234313966633033643033326439656430616531636561656463
# 64373734393633383163333739303835326238386136366264643566623834353032
# 6533643331363039620a303234353663366636643039363933363535373264623737
# ...Le contenu est entièrement chiffré en AES-256. Sans le mot de passe Vault, il est impossible de lire les données.
ansible-vault edit : Modifier un fichier chiffré
La commande edit déchiffre temporairement le fichier en mémoire, ouvre votre éditeur, puis re-chiffre le fichier à la sauvegarde :
# Modifier un fichier chiffré existant
ansible-vault edit group_vars/production/vault.yml
# Vault password: (saisissez votre mot de passe)
# L'éditeur s'ouvre avec le contenu déchiffré
# Modifiez, sauvegardez, quittez — le fichier est re-chiffréLe fichier déchiffré n'est jamais écrit sur le disque en clair. Le déchiffrement se fait en mémoire, ce qui garantit qu'aucune trace en clair ne reste sur le système de fichiers.
ansible-vault view : Afficher un fichier chiffré
Pour simplement consulter le contenu d'un fichier chiffré sans le modifier :
# Afficher le contenu déchiffré dans le terminal
ansible-vault view group_vars/production/vault.yml
# Vault password:
# vault_db_password: "S3cur3P@ssw0rd!"
# vault_api_key: "ak_live_xxxxxxxxxxx"
# vault_ssl_passphrase: "M0nCert1f1cat!"ansible-vault encrypt : Chiffrer un fichier existant
Si vous avez un fichier en clair que vous souhaitez chiffrer a posteriori :
# Chiffrer un fichier existant en clair
ansible-vault encrypt secrets.yml
# New Vault password:
# Confirm New Vault password:
# Encryption successful
# Vous pouvez aussi chiffrer plusieurs fichiers en une seule commande
ansible-vault encrypt fichier1.yml fichier2.yml fichier3.ymlAttention : après le chiffrement, assurez-vous que le fichier en clair n'est plus accessible. Si le fichier était déjà versionné en clair dans Git, l'historique contient toujours la version non chiffrée. Nous verrons plus loin comment gérer cette situation.
ansible-vault decrypt : Déchiffrer un fichier
L'opération inverse du chiffrement :
# Déchiffrer un fichier (le remplace par la version en clair)
ansible-vault decrypt secrets.yml
# Vault password:
# Decryption successful
# Le fichier est maintenant en clair sur le disque
# ATTENTION : ne commitez jamais un fichier déchiffré !Cette commande est utile pour des opérations de maintenance, mais doit être utilisée avec précaution. Ne laissez jamais un fichier déchiffré traîner sur le disque.
ansible-vault encrypt_string : Chiffrer une variable individuelle
C'est l'une des fonctionnalités les plus puissantes de Vault. Au lieu de chiffrer un fichier entier, vous pouvez chiffrer une seule variable et l'intégrer directement dans un fichier YAML par ailleurs lisible :
# Chiffrer une chaîne avec un nom de variable
ansible-vault encrypt_string 'S3cur3P@ssw0rd!' --name 'vault_db_password'
# Vault password:
# Résultat :
# vault_db_password: !vault |
# $ANSIBLE_VAULT;1.1;AES256
# 61326634653738373163356364373961653931363...
# 3365653230383963380a623435343933363533366...
# 6432326265636664640a313732323965376565626...
# Chiffrer depuis stdin (utile pour les mots de passe complexes)
echo -n 'MonMotDePasse' | ansible-vault encrypt_string --stdin-name 'vault_password'
# Chiffrer en mode interactif
ansible-vault encrypt_string --ask-vault-pass --name 'vault_secret'
# Saisissez la valeur puis Ctrl+D pour terminerVous pouvez ensuite copier-coller la sortie directement dans votre fichier de variables :
# group_vars/all.yml — Mélange de variables en clair et chiffrées
---
# Variables publiques (lisibles par tous)
app_name: mon_application
app_port: 3000
app_environment: production
db_host: db.example.com
db_name: app_production
db_user: app_user
# Variables sensibles (chiffrées individuellement)
vault_db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
61326634653738373163356364373961653931363032666232333232363564366262
3365653230383963380a623435343933363533366336363738623834623065643539
6432326265636664640a313732323965376565626233623538633539386131333761
3163
vault_api_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
34373565623430376136623462353832323335353530356165346333633335636163
6231353830306166350a333735656362613431393833373431613338333333393132
3834Cette approche est extrêmement pratique car elle permet de voir la structure du fichier et les noms des variables sans pouvoir lire les valeurs sensibles.
ansible-vault rekey : Changer le mot de passe Vault
Pour changer le mot de passe de chiffrement d'un ou plusieurs fichiers :
# Changer le mot de passe d'un fichier chiffré
ansible-vault rekey secrets.yml
# Vault password: (ancien mot de passe)
# New Vault password: (nouveau mot de passe)
# Confirm New Vault password:
# Rekey successful
# Rechiffrer plusieurs fichiers en même temps
ansible-vault rekey group_vars/production/vault.yml group_vars/staging/vault.ymlUtiliser un Fichier de Mot de Passe Vault
Saisir le mot de passe Vault manuellement à chaque exécution est fastidieux et incompatible avec l'automatisation CI/CD. Ansible permet d'utiliser un fichier de mot de passe pour automatiser le déchiffrement.
Créer un fichier de mot de passe
# Créer le fichier de mot de passe
echo 'MonMotDePasseVaultTresLong2024!' > ~/.vault_password
# CRUCIAL : restreindre les permissions
chmod 600 ~/.vault_password
# Vérifier les permissions
ls -la ~/.vault_password
# -rw------- 1 user user 32 Mar 7 10:00 /home/user/.vault_passwordUtiliser le fichier avec --vault-password-file
# Exécuter un playbook sans saisie interactive
ansible-playbook playbook.yml --vault-password-file ~/.vault_password
# Éditer un fichier chiffré sans saisie interactive
ansible-vault edit secrets.yml --vault-password-file ~/.vault_password
# Chiffrer un fichier sans saisie interactive
ansible-vault encrypt fichier.yml --vault-password-file ~/.vault_passwordConfigurer le fichier de mot de passe par défaut
Pour éviter de spécifier --vault-password-file à chaque commande, vous pouvez le configurer dans ansible.cfg :
# ansible.cfg
[defaults]
vault_password_file = ~/.vault_passwordAvec cette configuration, toutes les commandes Ansible utiliseront automatiquement ce fichier pour le déchiffrement.
Utiliser un script comme source de mot de passe
Ansible permet aussi d'utiliser un script exécutable comme source de mot de passe. Le script doit afficher le mot de passe sur stdout. C'est très utile pour récupérer le mot de passe depuis un gestionnaire de secrets externe :
#!/bin/bash
# ~/.vault_password_script.sh
# Récupérer le mot de passe depuis un gestionnaire de secrets
# Option 1 : Depuis une variable d'environnement
echo "${ANSIBLE_VAULT_PASSWORD}"
# Option 2 : Depuis le trousseau macOS
# security find-generic-password -a "ansible-vault" -s "vault-password" -w
# Option 3 : Depuis HashiCorp Vault
# vault kv get -field=password secret/ansible/vault
# Option 4 : Depuis AWS Secrets Manager
# aws secretsmanager get-secret-value --secret-id ansible-vault --query SecretString --output text# Rendre le script exécutable
chmod 700 ~/.vault_password_script.sh
# Utiliser le script
ansible-playbook playbook.yml --vault-password-file ~/.vault_password_script.sh
# Ou dans ansible.cfg
# vault_password_file = ~/.vault_password_script.shIntégration dans les Playbooks
Utiliser des fichiers de variables chiffrés
La méthode la plus courante consiste à chiffrer des fichiers de variables entiers et à les inclure dans vos playbooks avec vars_files :
# playbook.yml
---
- name: Déployer l'application
hosts: webservers
become: true
vars_files:
- vars/common.yml # Variables en clair
- vars/vault.yml # Variables chiffrées avec Vault
tasks:
- name: Configurer la base de données
ansible.builtin.template:
src: database.conf.j2
dest: /etc/app/database.conf
owner: app
group: app
mode: "0600"
- name: Configurer l'application
ansible.builtin.template:
src: app.conf.j2
dest: /etc/app/app.conf
owner: app
group: app
mode: "0644"
notify: Redémarrer application# vars/common.yml (en clair)
---
app_name: mon_application
app_port: 3000
db_host: db.production.local
db_name: app_production
db_user: app_user# vars/vault.yml (chiffré avec ansible-vault encrypt)
---
vault_db_password: "S3cur3P@ssw0rd!"
vault_api_key: "ak_live_xxxxxxxxxxxxxxxx"
vault_smtp_password: "smtp_p@ssw0rd"
vault_ssl_key_passphrase: "c3rt_p@ss"# Exécuter le playbook
ansible-playbook playbook.yml --ask-vault-pass
# Ou avec un fichier de mot de passe
ansible-playbook playbook.yml --vault-password-file ~/.vault_passwordAnsible détecte automatiquement que vars/vault.yml est chiffré et le déchiffre à la volée pendant l'exécution. Aucune modification du playbook n'est nécessaire.
Utiliser des variables inline chiffrées
Comme nous l'avons vu avec encrypt_string, vous pouvez mélanger variables en clair et variables chiffrées dans le même fichier :
# group_vars/production.yml
---
# Variables publiques
app_environment: production
app_debug: false
app_log_level: warning
# Variables sensibles chiffrées inline
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
33363965326261303234313966633033643033326439656430616531636561656463
64373734393633383163333739303835326238386136366264643566623834353032
6533643331363039620a303234353663366636643039363933363535373264623737
api_secret: !vault |
$ANSIBLE_VAULT;1.1;AES256
61326634653738373163356364373961653931363032666232333232363564366262
3365653230383963380a623435343933363533366336363738623834623065643539Variables chiffrées dans l'inventaire
Les variables chiffrées fonctionnent aussi dans les fichiers group_vars et host_vars :
# Structure de l'inventaire avec des fichiers Vault
inventory/
├── production/
│ ├── hosts.yml
│ ├── group_vars/
│ │ ├── all/
│ │ │ ├── vars.yml # Variables en clair
│ │ │ └── vault.yml # Variables chiffrées
│ │ ├── webservers/
│ │ │ ├── vars.yml
│ │ │ └── vault.yml
│ │ └── databases/
│ │ ├── vars.yml
│ │ └── vault.yml
│ └── host_vars/
│ └── db01.production.local/
│ ├── vars.yml
│ └── vault.ymlLa convention de nommer les fichiers chiffrés vault.yml est une bonne pratique. Elle rend immédiatement visible quels fichiers contiennent des secrets.
Multi-Vault IDs : Gérer Plusieurs Mots de Passe
Dans un environnement complexe, vous pourriez avoir besoin de différents mots de passe Vault pour différents environnements ou niveaux de sensibilité. Ansible supporte les Vault IDs pour gérer cette situation.
Concept des Vault IDs
Un Vault ID est un identifiant associé à un mot de passe Vault spécifique. Cela permet de chiffrer différents fichiers avec différents mots de passe et de fournir les bons mots de passe lors de l'exécution.
Chiffrer avec un Vault ID
# Chiffrer un fichier avec le Vault ID "production"
ansible-vault encrypt --vault-id production@prompt secrets_prod.yml
# Chiffrer un fichier avec le Vault ID "staging"
ansible-vault encrypt --vault-id staging@prompt secrets_staging.yml
# Chiffrer avec un Vault ID et un fichier de mot de passe
ansible-vault encrypt --vault-id production@~/.vault_pass_prod secrets_prod.yml
ansible-vault encrypt --vault-id staging@~/.vault_pass_staging secrets_staging.yml
# Chiffrer une variable avec un Vault ID
ansible-vault encrypt_string --vault-id production@prompt 'SecretProd' --name 'db_password'Le format est --vault-id LABEL@SOURCE où :
- LABEL est un identifiant libre (production, staging, dev, secrets, etc.).
- SOURCE peut être
prompt(saisie interactive), un chemin de fichier, ou un script.
Exécuter avec plusieurs Vault IDs
# Fournir plusieurs mots de passe Vault lors de l'exécution
ansible-playbook playbook.yml \
--vault-id production@~/.vault_pass_prod \
--vault-id staging@~/.vault_pass_staging
# Mélanger fichiers et saisie interactive
ansible-playbook playbook.yml \
--vault-id production@~/.vault_pass_prod \
--vault-id dev@promptExemple pratique multi-environnement
# Créer les fichiers de mots de passe par environnement
echo 'ProdVaultPass2024!' > ~/.vault_pass_prod
echo 'StagingVaultPass2024!' > ~/.vault_pass_staging
chmod 600 ~/.vault_pass_prod ~/.vault_pass_staging
# Chiffrer les secrets de production
ansible-vault encrypt \
--vault-id production@~/.vault_pass_prod \
inventory/production/group_vars/all/vault.yml
# Chiffrer les secrets de staging
ansible-vault encrypt \
--vault-id staging@~/.vault_pass_staging \
inventory/staging/group_vars/all/vault.yml# inventory/production/group_vars/all/vault.yml (avant chiffrement)
---
vault_db_password: "ProdDbP@ss2024!"
vault_api_key: "ak_prod_xxxxxxxx"
vault_smtp_password: "smtp_prod_p@ss"# inventory/staging/group_vars/all/vault.yml (avant chiffrement)
---
vault_db_password: "StagingDbPass123"
vault_api_key: "ak_staging_yyyyyyyy"
vault_smtp_password: "smtp_staging_pass"# Déployer en production (seul le mot de passe production est nécessaire)
ansible-playbook -i inventory/production playbook.yml \
--vault-id production@~/.vault_pass_prod
# Déployer en staging
ansible-playbook -i inventory/staging playbook.yml \
--vault-id staging@~/.vault_pass_stagingBonnes Pratiques de Sécurité
1. Ne jamais commiter de secrets en clair
C'est la règle numéro un, non négociable. Même si vous chiffrez le fichier plus tard, l'historique Git conserve la version en clair. Configurez votre .gitignore pour exclure les fichiers sensibles :
# .gitignore
# Fichiers de mots de passe Vault
.vault_password
.vault_pass_*
*.vault_password
# Fichiers déchiffrés temporaires
*.decrypted
*.dec
# Clés et certificats en clair
*.pem
*.key
*.p12
# Variables d'environnement
.env
.env.*2. Séparer variables et vault vars
Adoptez la convention de séparer les variables en clair et les variables chiffrées dans des fichiers distincts :
# group_vars/webservers/vars.yml — Variables en clair
---
app_name: mon_application
app_port: 3000
db_host: db.production.local
db_name: app_production
db_user: app_user
db_password: "{{ vault_db_password }}" # Référence à la variable Vault
api_key: "{{ vault_api_key }}" # Référence à la variable Vault# group_vars/webservers/vault.yml — Variables chiffrées
---
vault_db_password: "S3cur3P@ssw0rd!"
vault_api_key: "ak_live_xxxxxxxxxxxxxxxx"Cette convention offre plusieurs avantages :
- Le fichier
vars.ymlest lisible et montre la structure des variables. - Le fichier
vault.ymlcontient uniquement les valeurs sensibles. - Il est facile de voir quelles variables sont des secrets (celles préfixées par
vault_). - Lors d'un
ansible-vault view, vous voyez uniquement les secrets sans le bruit des variables publiques.
3. Préfixer les variables Vault
Préfixez systématiquement vos variables chiffrées avec vault_. Cela crée une distinction claire et permet de tracer facilement l'utilisation des secrets dans vos playbooks :
# Convention de nommage
vault_db_password: "..." # Mot de passe BDD
vault_api_key: "..." # Clé API
vault_ssl_cert_key: "..." # Clé privée SSL
vault_smtp_password: "..." # Mot de passe SMTP
vault_ssh_private_key: "..." # Clé SSH privée4. Utiliser des mots de passe Vault robustes
Le mot de passe Vault protège tous vos secrets. Il doit être suffisamment fort :
# Générer un mot de passe robuste
openssl rand -base64 48 > ~/.vault_password
chmod 600 ~/.vault_password
# Ou avec pwgen
pwgen -s 64 1 > ~/.vault_password
chmod 600 ~/.vault_password
# Vérifier les permissions
stat -c '%a %U:%G' ~/.vault_password
# 600 user:user5. Protéger le fichier de mot de passe
# Permissions strictes (lecture/écriture uniquement pour le propriétaire)
chmod 600 ~/.vault_password
# Vérifier que le fichier n'est PAS dans un dépôt Git
git status ~/.vault_password # Ne doit pas être traqué
# Ajouter à .gitignore global
echo '.vault_password' >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global6. Auditer l'utilisation des secrets
Vérifiez régulièrement que vos secrets ne sont pas exposés accidentellement :
# Chercher des mots de passe potentiellement en clair dans le projet
grep -rn "password:" --include="*.yml" --include="*.yaml" . | grep -v vault | grep -v "{{"
# Chercher des clés API en clair
grep -rn "api_key\|api_secret\|token" --include="*.yml" . | grep -v vault | grep -v "{{"
# Vérifier que tous les fichiers vault sont bien chiffrés
find . -name "vault.yml" -exec head -1 {} \; | grep -v ANSIBLE_VAULT
# Si cette commande retourne quelque chose, un fichier vault n'est pas chiffré !Intégration CI/CD
L'intégration d'Ansible Vault dans un pipeline CI/CD nécessite de rendre le mot de passe disponible sans intervention humaine, tout en le gardant sécurisé.
Variable d'environnement ANSIBLE_VAULT_PASSWORD_FILE
La variable d'environnement ANSIBLE_VAULT_PASSWORD_FILE permet de spécifier le fichier de mot de passe sans modifier ansible.cfg :
# Définir la variable d'environnement
export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_password
# Toutes les commandes Ansible utiliseront automatiquement ce fichier
ansible-playbook playbook.yml # Pas besoin de --ask-vault-passIntégration avec GitLab CI
# .gitlab-ci.yml
---
stages:
- test
- deploy
variables:
ANSIBLE_FORCE_COLOR: "true"
.ansible_base:
image: python:3.11-slim
before_script:
- pip install ansible
# Créer le fichier de mot de passe à partir de la variable CI/CD
- echo "${VAULT_PASSWORD}" > /tmp/vault_password
- chmod 600 /tmp/vault_password
- export ANSIBLE_VAULT_PASSWORD_FILE=/tmp/vault_password
after_script:
# Supprimer le fichier de mot de passe après utilisation
- rm -f /tmp/vault_password
test_playbook:
extends: .ansible_base
stage: test
script:
- ansible-playbook --check -i inventory/staging playbook.yml
only:
- merge_requests
deploy_staging:
extends: .ansible_base
stage: deploy
script:
- ansible-playbook -i inventory/staging playbook.yml
only:
- develop
environment:
name: staging
deploy_production:
extends: .ansible_base
stage: deploy
script:
- ansible-playbook -i inventory/production playbook.yml
only:
- main
when: manual
environment:
name: productionLa variable VAULT_PASSWORD est configurée dans les CI/CD Variables de GitLab (Settings > CI/CD > Variables) en mode "masked" et "protected".
Intégration avec GitHub Actions
# .github/workflows/deploy.yml
---
name: Deploy with Ansible
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout du code
uses: actions/checkout@v4
- name: Installer Python et Ansible
run: |
python -m pip install --upgrade pip
pip install ansible
- name: Installer les dépendances Galaxy
run: |
ansible-galaxy install -r requirements.yml
ansible-galaxy collection install -r requirements.yml
- name: Créer le fichier de mot de passe Vault
run: |
echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > /tmp/vault_password
chmod 600 /tmp/vault_password
- name: Exécuter le playbook
env:
ANSIBLE_VAULT_PASSWORD_FILE: /tmp/vault_password
ANSIBLE_HOST_KEY_CHECKING: "false"
run: |
ansible-playbook -i inventory/production playbook.yml
- name: Nettoyer le fichier de mot de passe
if: always()
run: rm -f /tmp/vault_passwordIntégration avec Jenkins
# Jenkinsfile (Pipeline déclaratif)
pipeline {
agent any
environment {
ANSIBLE_VAULT_PASSWORD_FILE = credentials('ansible-vault-password')
}
stages {
stage('Prepare') {
steps {
sh 'pip install ansible'
sh 'ansible-galaxy install -r requirements.yml'
}
}
stage('Test') {
steps {
sh 'ansible-playbook --check -i inventory/staging playbook.yml'
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh 'ansible-playbook -i inventory/production playbook.yml'
}
}
}
post {
always {
sh 'rm -f /tmp/vault_*'
}
}
}Rotation des Mots de Passe Vault
La rotation régulière des mots de passe Vault est une bonne pratique de sécurité. Voici comment procéder méthodiquement.
Processus de rotation
#!/bin/bash
# rotate_vault_password.sh — Script de rotation du mot de passe Vault
set -euo pipefail
VAULT_FILES=$(find . -name "vault.yml" -type f)
OLD_PASS_FILE=~/.vault_password
NEW_PASS_FILE=~/.vault_password_new
# 1. Générer le nouveau mot de passe
echo "Génération du nouveau mot de passe..."
openssl rand -base64 48 > "${NEW_PASS_FILE}"
chmod 600 "${NEW_PASS_FILE}"
# 2. Rechiffrer tous les fichiers Vault
echo "Rechiffrement des fichiers Vault..."
for vault_file in ${VAULT_FILES}; do
echo " Rechiffrement de ${vault_file}..."
ansible-vault rekey \
--vault-password-file "${OLD_PASS_FILE}" \
--new-vault-password-file "${NEW_PASS_FILE}" \
"${vault_file}"
done
# 3. Remplacer l'ancien mot de passe par le nouveau
echo "Remplacement du fichier de mot de passe..."
mv "${NEW_PASS_FILE}" "${OLD_PASS_FILE}"
chmod 600 "${OLD_PASS_FILE}"
# 4. Mettre à jour la variable CI/CD (manuellement ou via API)
echo ""
echo "IMPORTANT : Mettez à jour la variable VAULT_PASSWORD dans votre CI/CD !"
echo "Nouveau mot de passe :"
cat "${OLD_PASS_FILE}"
echo ""
echo "Rotation terminée avec succès."# Exécuter le script de rotation
chmod +x rotate_vault_password.sh
./rotate_vault_password.shPlanification de la rotation
Établissez un calendrier de rotation adapté à votre contexte :
- Rotation régulière : tous les 3 à 6 mois pour les environnements standards.
- Rotation immédiate : lorsqu'un membre de l'équipe quitte le projet ou en cas de suspicion de compromission.
- Rotation après incident : si le fichier de mot de passe a pu être exposé.
Ansible Vault vs HashiCorp Vault
Une confusion fréquente existe entre Ansible Vault et HashiCorp Vault. Ce sont deux outils très différents qui peuvent être complémentaires.
Ansible Vault
- Type : outil de chiffrement de fichiers intégré à Ansible.
- Fonction : chiffrer des fichiers YAML ou des variables individuelles avec AES-256.
- Stockage des secrets : les secrets chiffrés sont stockés dans les fichiers du projet (versionnés dans Git).
- Gestion des accès : quiconque possède le mot de passe Vault peut déchiffrer tous les secrets.
- Rotation : manuelle, nécessite de rechiffrer les fichiers.
- Audit : pas de journal d'accès intégré.
- Coût : gratuit, inclus dans Ansible.
- Complexité : très simple à mettre en place.
HashiCorp Vault
- Type : gestionnaire de secrets centralisé (service à part entière).
- Fonction : stocker, distribuer et faire tourner des secrets de manière centralisée.
- Stockage des secrets : les secrets sont stockés dans un backend sécurisé (mémoire, Consul, base de données chiffrée).
- Gestion des accès : contrôle d'accès fin avec des politiques, authentification multiple (LDAP, tokens, certificats, etc.).
- Rotation : automatique pour certains types de secrets (credentials de BDD, certificats).
- Audit : journal d'accès complet (qui a lu quel secret, quand).
- Coût : gratuit en version open source, payant pour la version Enterprise.
- Complexité : nécessite un déploiement et une maintenance dédiés.
Quand utiliser quoi ?
Ansible Vault est parfait pour les projets de petite à moyenne taille où les secrets sont peu nombreux et gérés par une équipe restreinte. C'est la solution la plus simple et la plus rapide à mettre en place.
HashiCorp Vault est recommandé pour les organisations qui gèrent des centaines de secrets, qui ont besoin de rotation automatique, de contrôle d'accès fin et de traçabilité complète. C'est un investissement en infrastructure mais qui offre des garanties de sécurité supérieures.
Les utiliser ensemble
Les deux outils ne sont pas mutuellement exclusifs. Une approche hybride courante consiste à utiliser HashiCorp Vault comme source de vérité pour les secrets et Ansible pour les récupérer au moment de l'exécution :
# playbook.yml — Récupérer des secrets depuis HashiCorp Vault
---
- name: Déploiement avec secrets HashiCorp Vault
hosts: webservers
become: true
tasks:
- name: Lire les secrets depuis HashiCorp Vault
community.hashi_vault.vault_read:
url: https://vault.entreprise.com
path: secret/data/app/production
auth_method: token
token: "{{ lookup('env', 'VAULT_TOKEN') }}"
register: vault_secrets
delegate_to: localhost
run_once: true
- name: Déployer la configuration avec les secrets
ansible.builtin.template:
src: app.conf.j2
dest: /etc/app/app.conf
owner: app
mode: "0600"
vars:
db_password: "{{ vault_secrets.data.data.db_password }}"
api_key: "{{ vault_secrets.data.data.api_key }}"Vous pouvez aussi utiliser le plugin lookup de HashiCorp Vault directement dans vos variables :
# group_vars/all.yml
---
db_password: "{{ lookup('community.hashi_vault.hashi_vault', 'secret/data/app:db_password') }}"
api_key: "{{ lookup('community.hashi_vault.hashi_vault', 'secret/data/app:api_key') }}"Exemples Complets de Chiffrement et Déchiffrement
Mettons tout en pratique avec un scénario complet de gestion des secrets pour un projet Ansible de production.
Mise en place initiale
# 1. Créer la structure du projet
mkdir -p mon_projet/{inventory/{production,staging}/{group_vars/all,host_vars},playbooks,roles}
cd mon_projet
# 2. Générer un mot de passe Vault robuste
openssl rand -base64 48 > ~/.vault_password_mon_projet
chmod 600 ~/.vault_password_mon_projet
# 3. Configurer ansible.cfg
cat > ansible.cfg << 'EOF'
[defaults]
inventory = inventory/production
roles_path = roles
vault_password_file = ~/.vault_password_mon_projet
host_key_checking = False
[privilege_escalation]
become = True
become_method = sudo
EOFCréer les fichiers de variables
# 4. Créer les variables en clair pour la production
cat > inventory/production/group_vars/all/vars.yml << 'EOF'
---
# Variables publiques
app_name: mon_application
app_port: 3000
app_environment: production
app_log_level: warning
# Base de données
db_host: db.production.local
db_port: 5432
db_name: app_production
db_user: app_user
db_password: "{{ vault_db_password }}"
# API externe
api_url: https://api.service-externe.com
api_key: "{{ vault_api_key }}"
# Email
smtp_host: smtp.gmail.com
smtp_port: 587
smtp_user: notifications@codeclan.fr
smtp_password: "{{ vault_smtp_password }}"
EOF
# 5. Créer le fichier de secrets
cat > inventory/production/group_vars/all/vault.yml << 'EOF'
---
vault_db_password: "Pr0duct10n_DB_P@ss_2024!"
vault_api_key: "ak_live_7f8a9b2c3d4e5f6g7h8i9j0k"
vault_smtp_password: "xvfb pqrs tuvw xyz1"
vault_ssl_cert_passphrase: "SSL_C3rt_P@ss!"
vault_deploy_token: "glpat-xxxxxxxxxxxxxxxxxxxx"
EOF
# 6. Chiffrer le fichier de secrets
ansible-vault encrypt inventory/production/group_vars/all/vault.yml
# Vérifier que le chiffrement a fonctionné
head -1 inventory/production/group_vars/all/vault.yml
# $ANSIBLE_VAULT;1.1;AES256Utiliser les secrets dans un playbook
# playbooks/deploy.yml
---
- name: Déployer l'application en production
hosts: webservers
become: true
tasks:
- name: Créer le répertoire de configuration
ansible.builtin.file:
path: /etc/{{ app_name }}
state: directory
owner: root
group: root
mode: "0755"
- name: Déployer la configuration de l'application
ansible.builtin.template:
src: templates/app.env.j2
dest: "/etc/{{ app_name }}/.env"
owner: "{{ app_name }}"
group: "{{ app_name }}"
mode: "0600" # Lecture/écriture uniquement pour le propriétaire
notify: Redémarrer application
- name: Déployer la configuration de la base de données
ansible.builtin.template:
src: templates/database.yml.j2
dest: "/etc/{{ app_name }}/database.yml"
owner: "{{ app_name }}"
group: "{{ app_name }}"
mode: "0600"
notify: Redémarrer application
handlers:
- name: Redémarrer application
ansible.builtin.service:
name: "{{ app_name }}"
state: restarted# templates/app.env.j2
APP_NAME={{ app_name }}
APP_PORT={{ app_port }}
APP_ENV={{ app_environment }}
LOG_LEVEL={{ app_log_level }}
# Base de données (secret déchiffré automatiquement)
DATABASE_URL=postgresql://{{ db_user }}:{{ db_password }}@{{ db_host }}:{{ db_port }}/{{ db_name }}
# API externe (secret déchiffré automatiquement)
API_URL={{ api_url }}
API_KEY={{ api_key }}
# SMTP (secret déchiffré automatiquement)
SMTP_HOST={{ smtp_host }}
SMTP_PORT={{ smtp_port }}
SMTP_USER={{ smtp_user }}
SMTP_PASSWORD={{ smtp_password }}Opérations courantes
# Voir les secrets actuels
ansible-vault view inventory/production/group_vars/all/vault.yml
# Modifier un secret
ansible-vault edit inventory/production/group_vars/all/vault.yml
# Ajouter un nouveau secret chiffré inline
ansible-vault encrypt_string 'NouveauSecret2024!' --name 'vault_nouveau_secret'
# Copier la sortie dans vault.yml
# Exécuter le playbook (le déchiffrement est automatique grâce à ansible.cfg)
ansible-playbook playbooks/deploy.yml
# Exécuter en mode check (dry-run)
ansible-playbook playbooks/deploy.yml --check --diff
# Vérifier qu'aucun secret n'apparaît dans la sortie (mode no_log)
ansible-playbook playbooks/deploy.yml -vProtéger la sortie Ansible avec no_log
Par défaut, Ansible peut afficher les valeurs des variables dans sa sortie (mode verbose). Pour empêcher l'affichage des secrets, utilisez no_log: true :
# Protéger les tâches manipulant des secrets
- name: Configurer l'accès à la base de données
ansible.builtin.template:
src: database.conf.j2
dest: /etc/app/database.conf
no_log: true # Empêche l'affichage du contenu dans les logs
- name: Définir le mot de passe de l'utilisateur
ansible.builtin.user:
name: deploy
password: "{{ vault_deploy_password | password_hash('sha512') }}"
no_log: true # CRUCIAL pour les mots de passeDépannage et Erreurs Courantes
Erreur : "Attempting to decrypt but no vault secrets found"
# Cause : pas de mot de passe Vault fourni
# Solution 1 : fournir le mot de passe
ansible-playbook playbook.yml --ask-vault-pass
# Solution 2 : configurer le fichier de mot de passe
ansible-playbook playbook.yml --vault-password-file ~/.vault_password
# Solution 3 : configurer dans ansible.cfg
# vault_password_file = ~/.vault_passwordErreur : "Decryption failed"
# Cause : mauvais mot de passe Vault
# Vérifiez que vous utilisez le bon mot de passe
ansible-vault view fichier.yml --ask-vault-pass
# Si vous avez plusieurs Vault IDs, vérifiez que vous fournissez le bon
ansible-vault view fichier.yml --vault-id production@promptErreur : "input is not vault encrypted data"
# Cause : le fichier n'est pas chiffré ou est corrompu
# Vérifiez l'en-tête du fichier
head -1 fichier.yml
# Devrait afficher : $ANSIBLE_VAULT;1.1;AES256
# Si le fichier n'est pas chiffré, chiffrez-le
ansible-vault encrypt fichier.ymlDéboguer les variables Vault
# Pour vérifier qu'une variable Vault est correctement déchiffrée
# ATTENTION : utilisez uniquement en développement, jamais en production !
- name: Debug variable Vault (DEV UNIQUEMENT)
ansible.builtin.debug:
msg: "La longueur du mot de passe est {{ vault_db_password | length }} caractères"
# Ne PAS afficher la valeur elle-même !
# msg: "{{ vault_db_password }}" # DANGEREUX !Conclusion
Ansible Vault est un outil essentiel pour tout projet Ansible professionnel. Il offre un mécanisme de chiffrement simple mais robuste qui s'intègre naturellement dans le workflow Ansible existant. En suivant les bonnes pratiques présentées dans cet article — séparation des variables et des secrets, convention de nommage vault_, fichiers de mot de passe sécurisés, intégration CI/CD — vous protégez vos secrets sans ajouter de complexité excessive à votre projet.
Les points essentiels à retenir :
- Chiffrez systématiquement tout ce qui est sensible avec
ansible-vault encryptouencrypt_string. - Séparez les variables en clair (
vars.yml) des secrets (vault.yml) avec une convention de nommagevault_. - Automatisez le déchiffrement en CI/CD avec
ANSIBLE_VAULT_PASSWORD_FILEet des variables de pipeline protégées. - Utilisez multi-vault pour des mots de passe différents par environnement.
- Protégez la sortie avec
no_log: truesur les tâches manipulant des secrets. - Planifiez la rotation régulière de vos mots de passe Vault.
- Pour les besoins avancés (rotation automatique, audit, contrôle d'accès fin), envisagez HashiCorp Vault en complément.
Avec cette série d'articles sur les rôles, Ansible Galaxy et Ansible Vault, vous disposez désormais de toutes les connaissances nécessaires pour construire une automatisation Ansible modulaire, réutilisable et sécurisée. Il ne reste plus qu'à mettre en pratique dans vos projets !