Module 4 : Sécurité & Secrets - Ansible Vault
Objectif du Module
Maîtriser Ansible Vault pour chiffrer et gérer les données sensibles (mots de passe, clés API, certificats), éviter les fuites de secrets dans Git, et déployer des infrastructures sécurisées conformes aux standards SecNumCloud et RGPD.
Durée : 2h30
Introduction : Le Problème des Secrets en Clair
Secrets in Git = Game Over
"Secrets in Git = Game Over." — Principe fondamental DevSecOps
Le scénario catastrophe (trop fréquent) :
# playbook.yml - COMMIT SUR GIT PUBLIC
---
- name: Déployer MySQL
hosts: db
vars:
mysql_root_password: SuperSecret123 # ❌ EN CLAIR!
api_key: sk-abc123xyz456 # ❌ EN CLAIR!
aws_access_key: AKIAIOSFODNN7EXAMPLE # ❌ EN CLAIR!
tasks:
- name: Configurer MySQL
mysql_user:
name: root
password: "{{ mysql_root_password }}"
Conséquences d'un commit de secrets :
- Indexation immédiate par les bots : GitHub/GitLab scannés en permanence
- Révocation impossible : L'historique Git garde TOUT (même après suppression)
- Compromission complète : Accès BDD, APIs, Cloud = faille totale
- Coût financier : Factures AWS/Azure à 5 chiffres en quelques heures
- RGPD : Fuite de données = amende jusqu'à 4% du CA mondial
Statistiques Alarmantes
Étude GitGuardian 2024 :
- 10 millions de secrets exposés publiquement sur GitHub en 2023
- 1 secret committé toutes les 3 secondes
- 67% des secrets ne sont JAMAIS révoqués après découverte
- Temps moyen de détection : 4-6 mois (trop tard)
Exemples réels de fuites :
| Entreprise | Secret fuité | Coût |
|---|---|---|
| Uber (2016) | Clés AWS dans repo privé hacké | $148M (amende) |
| Tesla (2018) | Credentials Kubernetes publics | Minage crypto sur infra |
| Toyota (2023) | Token GitHub public | 300k clients exposés |
Message clair : JAMAIS de secrets en clair dans Git.
Concept : Ansible Vault
Qu'est-ce qu'Ansible Vault ?
Définition : Ansible Vault est un système de chiffrement AES-256 intégré à Ansible pour protéger les fichiers et variables contenant des données sensibles.
Analogie : Si Git est un "coffre-fort transparent" (tout le monde voit le contenu), Vault est un "cadenas numérique" qui rend les fichiers illisibles sans la clé.
Fonctionnement :
Fichier en clair Ansible Vault Fichier chiffré
───────────────── ──────────── ────────────────
mysql_password: Secret ansible-vault encrypt $ANSIBLE_VAULT;1.1;AES256
api_key: abc123 ──────────────> 66386439653865...
Mot de passe: **** 39383437643037...
[ILLISIBLE]
Avantages :
- ✅ Chiffrement AES-256 : Standard militaire (NSA Suite B)
- ✅ Intégré à Ansible : Aucun outil externe
- ✅ Transparent : Ansible déchiffre automatiquement à l'exécution
- ✅ Versionnable : Fichiers chiffrés safe dans Git
- ✅ Auditable : Changements de secrets trackés (contenu chiffré)
Limitations :
- ⚠️ 1 mot de passe = 1 fichier : Rotation complexe
- ⚠️ Pas de gestion centralisée : HashiCorp Vault pour ça
- ⚠️ Déchiffrement en RAM : Secrets exposés pendant exécution
Files vs Strings - Deux Approches
Ansible Vault supporte 2 niveaux de chiffrement :
1. Chiffrement de Fichiers Complets (Recommandé)
Fichier secrets.yml en clair :
---
mysql_root_password: SuperSecret123
api_key: sk-abc123xyz456
ssl_private_key: |
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC...
-----END PRIVATE KEY-----
Après ansible-vault encrypt secrets.yml :
$ANSIBLE_VAULT;1.1;AES256
66386439653865343966386166373038343037643037613962613834373530373938663834353033
3339613437663766623961393339326365303231313738330a373539656231303637383031613039
62333637353061636365373764633264393434313035303061363339326237653365373839643566
6265313464656635620a653665356232303738663037346337363837366536386137656232656335
...
[200+ lignes de hash illisible]
Utilisation dans playbook :
---
- hosts: db
vars_files:
- secrets.yml # Ansible déchiffre automatiquement
tasks:
- name: Configurer MySQL
mysql_user:
password: "{{ mysql_root_password }}"
Avantages :
- ✅ Tous les secrets dans 1 fichier centralisé
- ✅ Facile à gérer (1 commande pour encrypt/decrypt)
- ✅ Historique Git protégé (tout le fichier chiffré)
2. Chiffrement de Variables Inline (Avancé)
Pour chiffrer UNE SEULE variable dans un fichier mixte :
# group_vars/db.yml - Fichier PARTIELLEMENT chiffré
---
# Variables publiques (en clair)
mysql_port: 3306
mysql_host: localhost
# Variable secrète (chiffrée inline)
mysql_root_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653865343966386166373038343037643037613962613834373530373938663834353033
3339613437663766623961393339326365303231313738330a373539656231303637383031613039
...
Avantages :
- ✅ Mélange clair + chiffré dans même fichier
- ✅ Historique Git lisible pour variables publiques
- ✅ Granularité fine (secret par secret)
Inconvénient :
- ⚠️ Plus complexe à gérer (chiffrer variable par variable)
Commande pour chiffrer une string :
Sortie :
mysql_root_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653865343966386166373038343037643037613962613834373530373938663834353033
...
Copier-coller cette sortie dans votre fichier YAML.
Pratique : Commandes Ansible Vault
Les 5 Commandes Essentielles
1. ansible-vault create - Créer un Fichier Chiffré
Créer un nouveau fichier chiffré :
Workflow :
- Demande un mot de passe Vault (à mémoriser !)
- Demande confirmation du mot de passe
- Ouvre l'éditeur par défaut (vim/nano)
- Saisir le contenu YAML
- Sauvegarder et quitter → fichier immédiatement chiffré
Exemple de saisie dans l'éditeur :
---
mysql_root_password: SuperSecret123
api_key: sk-abc123xyz456
aws_access_key: AKIAIOSFODNN7EXAMPLE
aws_secret_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Après sauvegarde, cat secrets.yml affiche :
$ANSIBLE_VAULT;1.1;AES256
66386439653865343966386166373038343037643037613962613834373530373938663834353033
...
2. ansible-vault edit - Éditer un Fichier Chiffré
Modifier un fichier chiffré existant :
Workflow :
- Demande le mot de passe Vault
- Déchiffre temporairement le fichier
- Ouvre l'éditeur avec le contenu en clair
- Modifications possibles
- Sauvegarder → re-chiffrement automatique
Exemple d'utilisation :
# Ajouter une nouvelle variable
ansible-vault edit secrets.yml
# Dans l'éditeur, ajouter :
# ssl_certificate_password: CertSecret456
# Sauvegarder → fichier re-chiffré avec la nouvelle variable
3. ansible-vault view - Visualiser un Fichier Chiffré
Afficher le contenu déchiffré sans éditer :
Demande le mot de passe → Affiche le contenu en clair :
Sortie en lecture seule (pas de modification).
Utile pour :
- Vérifier rapidement une valeur
- Copier un secret dans le terminal
- Debugging sans risque de modification accidentelle
4. ansible-vault encrypt - Chiffrer un Fichier Existant
Chiffrer un fichier YAML existant :
# Fichier en clair
cat secrets.yml
# mysql_root_password: SuperSecret123
# Chiffrement
ansible-vault encrypt secrets.yml
# New Vault password: ****
# Confirm New Vault password: ****
# Encryption successful
# Fichier maintenant chiffré
cat secrets.yml
# $ANSIBLE_VAULT;1.1;AES256
# 66386439653865...
Options utiles :
# Chiffrer plusieurs fichiers d'un coup
ansible-vault encrypt secrets.yml db_passwords.yml api_keys.yml
# Spécifier le mot de passe en ligne (DANGEREUX, à éviter)
ansible-vault encrypt secrets.yml --vault-password-file .vault_pass
5. ansible-vault decrypt - Déchiffrer un Fichier
Déchiffrer un fichier (⚠️ ATTENTION : fichier en clair après) :
ansible-vault decrypt secrets.yml
# Vault password: ****
# Decryption successful
# Fichier maintenant en clair
cat secrets.yml
# mysql_root_password: SuperSecret123
⚠️ DANGER : Ne déchiffrer que temporairement, JAMAIS commit en clair !
Usage recommandé :
# Déchiffrer pour modification manuelle
ansible-vault decrypt secrets.yml
nano secrets.yml
# ... modifications ...
# RE-CHIFFRER IMMÉDIATEMENT
ansible-vault encrypt secrets.yml
# VÉRIFIER que le fichier est chiffré avant commit
cat secrets.yml | head -1
# $ANSIBLE_VAULT;1.1;AES256 ← OK, chiffré
Chiffrer des Variables Individuelles
ansible-vault encrypt_string - Chiffrer une Chaîne
Chiffrer une variable pour usage inline :
Sortie :
mysql_root_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653865343966386166373038343037643037613962613834373530373938663834353033
3339613437663766623961393339326365303231313738330a373539656231303637383031613039
...
Copier-coller dans votre fichier YAML :
# group_vars/db.yml
mysql_port: 3306
mysql_root_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653865343966386166373038343037643037613962613834373530373938663834353033
...
Lire depuis stdin (utile pour scripts) :
Pratique : Gestion des Mots de Passe Vault
Problème : Entrer le Mot de Passe à Chaque Fois
Par défaut, Ansible demande le mot de passe Vault :
Problème : Impossible pour automation (CI/CD, cron jobs).
Solution 1 : --ask-vault-pass (Interactif)
Pour exécution manuelle :
Avantages :
- ✅ Sécurisé (mot de passe pas stocké)
- ✅ Audit (qui a exécuté)
Inconvénients :
- ❌ Manuel (pas d'automation)
- ❌ Fastidieux (répétitif)
Solution 2 : Fichier .vault_pass (Automation)
Créer un fichier contenant le mot de passe :
echo 'VotreMotDePasseVault' > .vault_pass
# CRITIQUE : Protéger le fichier
chmod 600 .vault_pass
# AJOUTER AU .gitignore (OBLIGATOIRE)
echo '.vault_pass' >> .gitignore
Utilisation :
Configuration permanente dans ansible.cfg :
Après configuration, plus besoin de spécifier l'option :
⚠️ SÉCURITÉ :
- ✅
.vault_passdans.gitignore - ✅ Permissions 600 (lisible uniquement par propriétaire)
- ✅ Stocké hors du repo Git (ou chiffré avec GPG)
- ❌ JAMAIS commiter
.vault_passen clair
Solution 3 : Script de Récupération (Avancé)
Pour intégration avec gestionnaires de secrets (1Password, Bitwarden, etc.) :
# vault_password_script.sh
#!/bin/bash
# Récupérer le mot de passe depuis 1Password
op read "op://vault/ansible-vault/password"
Rendre exécutable :
Utilisation :
Ansible exécute le script et utilise sa sortie comme mot de passe.
Solution 4 : Variables d'Environnement (CI/CD)
Pour pipelines GitLab CI / GitHub Actions :
GitLab CI .gitlab-ci.yml :
deploy:
script:
- echo "$VAULT_PASSWORD" > .vault_pass
- ansible-playbook site.yml --vault-password-file .vault_pass
- rm .vault_pass # Nettoyage
variables:
VAULT_PASSWORD:
value: VotreMotDePasseVault
protected: true
masked: true
GitHub Actions .github/workflows/deploy.yml :
- name: Deploy with Ansible
env:
VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}
run: |
echo "$VAULT_PASSWORD" > .vault_pass
ansible-playbook site.yml --vault-password-file .vault_pass
rm .vault_pass
Secrets stockés dans GitHub Secrets / GitLab CI Variables (chiffrés).
Pratique : Intégration dans les Playbooks
Charger des Fichiers Chiffrés avec vars_files
Playbook site.yml :
---
- name: Déployer application avec secrets
hosts: all
become: yes
vars_files:
- secrets.yml # Fichier chiffré avec Vault
tasks:
- name: Afficher le mot de passe (DEBUG - À SUPPRIMER EN PROD)
debug:
msg: "Mot de passe MySQL : {{ mysql_root_password }}"
- name: Configurer MySQL
mysql_user:
name: root
password: "{{ mysql_root_password }}"
host: localhost
state: present
Exécution :
ansible-playbook site.yml --ask-vault-pass
# Vault password: ****
# PLAY [Déployer application avec secrets] ****
# TASK [Afficher le mot de passe] ****
# ok: [localhost] => {
# "msg": "Mot de passe MySQL : SuperSecret123"
# }
Ansible déchiffre automatiquement secrets.yml à l'exécution.
Variables Inline Chiffrées avec !vault |
Fichier group_vars/db.yml :
---
# Variables publiques
mysql_port: 3306
mysql_host: localhost
mysql_database: production_db
# Variable secrète (chiffrée inline)
mysql_root_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653865343966386166373038343037643037613962613834373530373938663834353033
3339613437663766623961393339326365303231313738330a373539656231303637383031613039
62333637353061636365373764633264393434313035303061363339326237653365373839643566
6265313464656635620a653665356232303738663037346337363837366536386137656232656335
3632
Playbook utilisant ces variables :
---
- name: Configuration MySQL
hosts: db
# Pas de vars_files, variables chargées depuis group_vars/db.yml
tasks:
- name: Installer MySQL
apt:
name: mysql-server
state: present
- name: Configurer root password
mysql_user:
name: root
password: "{{ mysql_root_password }}"
Exécution :
Ansible déchiffre automatiquement la variable !vault |.
Best Practices de Structuration
Organisation recommandée :
ansible-project/
├── ansible.cfg
├── inventory/
│ └── production.ini
├── group_vars/
│ ├── all.yml # Variables publiques
│ ├── web.yml # Variables publiques web
│ └── db.yml # Variables publiques db
├── secrets/
│ ├── all_secrets.yml # Secrets communs (CHIFFRÉ)
│ ├── web_secrets.yml # Secrets web (CHIFFRÉ)
│ └── db_secrets.yml # Secrets db (CHIFFRÉ)
├── playbooks/
│ └── site.yml
└── .gitignore # .vault_pass, *.retry
Playbook chargeant les secrets :
---
- name: Déploiement complet
hosts: all
vars_files:
- ../secrets/all_secrets.yml
- name: Serveurs Web
hosts: web
vars_files:
- ../secrets/web_secrets.yml
roles:
- nginx
- name: Serveurs DB
hosts: db
vars_files:
- ../secrets/db_secrets.yml
roles:
- mysql
Avantages :
- ✅ Séparation clair/chiffré
- ✅ Secrets groupés par fonction
- ✅ Audit facilité (historique Git des secrets chiffrés)
Exercice : Base de Données Sécurisée
Scénario
Vous devez déployer un serveur MySQL avec un mot de passe root chiffré dans Vault.
Contraintes :
- ❌ Interdiction formelle de stocker le mot de passe en clair
- ✅ Le mot de passe doit être dans un fichier
secrets.ymlchiffré - ✅ Le playbook doit installer MySQL et configurer le mot de passe
- ✅ L'exécution doit demander le mot de passe Vault
Mission
- Créer un fichier chiffré
secrets.ymlcontenant : -
Variable
mysql_root_passwordavec la valeurSuperSecret123 -
Créer un playbook
deploy_mysql.ymlqui : - Charge
secrets.yml - Installe MySQL Server
-
Configure le mot de passe root
-
Exécuter le playbook en demandant le mot de passe Vault
Étapes Détaillées
Étape 1 : Créer le Fichier de Secrets Chiffré
Dans l'éditeur, saisir :
---
mysql_root_password: SuperSecret123
mysql_database: production_db
mysql_user: app_user
mysql_user_password: AppSecret456
Sauvegarder et quitter → fichier immédiatement chiffré.
Vérifier le chiffrement :
Étape 2 : Créer le Playbook
Fichier deploy_mysql.yml :
---
- name: Déploiement MySQL sécurisé
hosts: db
become: yes
vars_files:
- secrets.yml
tasks:
- name: Installer MySQL Server
apt:
name:
- mysql-server
- python3-pymysql
state: present
update_cache: yes
- name: Démarrer MySQL
service:
name: mysql
state: started
enabled: yes
- name: Configurer le mot de passe root MySQL
mysql_user:
name: root
password: "{{ mysql_root_password }}"
host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
state: present
- name: Créer la base de données
mysql_db:
name: "{{ mysql_database }}"
state: present
login_unix_socket: /var/run/mysqld/mysqld.sock
- name: Créer l'utilisateur applicatif
mysql_user:
name: "{{ mysql_user }}"
password: "{{ mysql_user_password }}"
priv: "{{ mysql_database }}.*:ALL"
host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
state: present
Étape 3 : Vérifier la Syntaxe
Étape 4 : Dry-Run
Étape 5 : Exécution Réelle
Sortie attendue :
Vault password: ****
PLAY [Déploiement MySQL sécurisé] ******************************************
TASK [Installer MySQL Server] **********************************************
changed: [db1]
TASK [Démarrer MySQL] ******************************************************
ok: [db1]
TASK [Configurer le mot de passe root MySQL] ******************************
changed: [db1]
TASK [Créer la base de données] ********************************************
changed: [db1]
TASK [Créer l'utilisateur applicatif] **************************************
changed: [db1]
PLAY RECAP ******************************************************************
db1 : ok=5 changed=4 unreachable=0 failed=0
Étape 6 : Validation
Vérifier que MySQL fonctionne avec le mot de passe :
# Sur le serveur db
mysql -u root -p
# Enter password: SuperSecret123
# mysql> ← ✅ Connexion réussie
Vérifier la base de données :
mysql -u root -pSuperSecret123 -e "SHOW DATABASES;"
# +--------------------+
# | Database |
# +--------------------+
# | production_db | ← ✅ Base créée
# +--------------------+
Vérifier l'utilisateur applicatif :
Solution
Solution Complète - Déploiement MySQL Sécurisé
Fichier secrets.yml (Chiffré)
Création :
Contenu (dans l'éditeur) :
---
mysql_root_password: SuperSecret123
mysql_database: production_db
mysql_user: app_user
mysql_user_password: AppSecret456
Après sauvegarde, vérifier :
Sortie (fichier chiffré) :
$ANSIBLE_VAULT;1.1;AES256
66386439653865343966386166373038343037643037613962613834373530373938663834353033
3339613437663766623961393339326365303231313738330a373539656231303637383031613039
62333637353061636365373764633264393434313035303061363339326237653365373839643566
6265313464656635620a653665356232303738663037346337363837366536386137656232656335
36323032373839663163373439633237383033373739326234653438623632626231653165646136
...
Fichier deploy_mysql.yml (Playbook)
---
- name: Déploiement MySQL sécurisé avec Vault
hosts: db
become: yes
vars_files:
- secrets.yml
vars:
mysql_bind_address: "0.0.0.0" # Écoute sur toutes les interfaces
tasks:
- name: Installer MySQL Server et dépendances Python
apt:
name:
- mysql-server
- python3-pymysql # Requis pour les modules mysql_*
state: present
update_cache: yes
tags:
- install
- name: Démarrer et activer MySQL
service:
name: mysql
state: started
enabled: yes
tags:
- service
- name: Configurer le mot de passe root MySQL
mysql_user:
name: root
password: "{{ mysql_root_password }}"
host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
state: present
tags:
- config
- name: Créer le fichier .my.cnf pour root
template:
src: root_my.cnf.j2
dest: /root/.my.cnf
owner: root
group: root
mode: '0600'
tags:
- config
- name: Créer la base de données
mysql_db:
name: "{{ mysql_database }}"
state: present
login_user: root
login_password: "{{ mysql_root_password }}"
tags:
- database
- name: Créer l'utilisateur applicatif
mysql_user:
name: "{{ mysql_user }}"
password: "{{ mysql_user_password }}"
priv: "{{ mysql_database }}.*:ALL"
host: "%" # Accès depuis n'importe quelle IP
login_user: root
login_password: "{{ mysql_root_password }}"
state: present
tags:
- users
- name: Supprimer les utilisateurs anonymes
mysql_user:
name: ""
host_all: yes
state: absent
login_user: root
login_password: "{{ mysql_root_password }}"
tags:
- security
- name: Supprimer la base de données test
mysql_db:
name: test
state: absent
login_user: root
login_password: "{{ mysql_root_password }}"
tags:
- security
Template templates/root_my.cnf.j2
Fichier de configuration MySQL pour root (évite de taper le mot de passe) :
⚠️ Permissions critiques : 600 (owner-readable only)
Fichier inventory.ini
[db]
db1 ansible_host=localhost ansible_connection=local
[db:vars]
ansible_python_interpreter=/usr/bin/python3
Fichier ansible.cfg (Optionnel)
[defaults]
inventory = inventory.ini
host_key_checking = False
# Optionnel : Spécifier le fichier de mot de passe Vault
# vault_password_file = .vault_pass
Commandes d'Exécution
1. Vérifier la syntaxe
2. Dry-run
Sortie :
Vault password: ****
PLAY [Déploiement MySQL sécurisé avec Vault] ******************************
TASK [Installer MySQL Server et dépendances Python] ***********************
changed: [db1]
...
PLAY RECAP *****************************************************************
db1 : ok=8 changed=6 unreachable=0 failed=0
3. Exécution réelle
4. Exécution avec fichier de mot de passe (automation)
Créer .vault_pass :
Exécution :
OU configurer dans ansible.cfg :
Puis simplement :
Validations Post-Déploiement
Vérifier que MySQL fonctionne :
Sortie :
Tester la connexion MySQL :
Sortie :
Vérifier la base de données :
Sortie :
db1 | CHANGED | rc=0 >>
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| production_db | ← ✅ Base créée
| sys |
+--------------------+
Tester l'utilisateur applicatif :
Sortie :
db1 | CHANGED | rc=0 >>
+------------------------------------------------------------+
| Grants for app_user@% |
+------------------------------------------------------------+
| GRANT USAGE ON *.* TO `app_user`@`%` |
| GRANT ALL PRIVILEGES ON `production_db`.* TO `app_user`@`%`|
+------------------------------------------------------------+
Sécurité Additionnelle (Bonus)
Vérifier que le fichier secrets.yml est chiffré :
Vérifier que .vault_pass est dans .gitignore :
Vérifier les permissions de .my.cnf :
Sortie :
db1 | CHANGED | rc=0 >>
-rw------- 1 root root 45 Nov 22 17:30 /root/.my.cnf
# ✅ Permissions 600 (owner-readable only)
Rotation du Mot de Passe (Bonus Avancé)
Pour changer le mot de passe Vault :
ansible-vault rekey secrets.yml
# Vault password: **** (ancien mot de passe)
# New Vault password: **** (nouveau mot de passe)
# Confirm New Vault password: ****
# Rekey successful
Le fichier est re-chiffré avec le nouveau mot de passe.
Intégration CI/CD (Bonus)
GitLab CI .gitlab-ci.yml :
deploy_mysql:
stage: deploy
script:
- echo "$VAULT_PASSWORD" > .vault_pass
- ansible-playbook deploy_mysql.yml --vault-password-file .vault_pass
- rm .vault_pass
only:
- main
variables:
VAULT_PASSWORD:
value: $VAULT_PASSWORD_SECRET
protected: true
masked: true
Variable VAULT_PASSWORD_SECRET définie dans Settings > CI/CD > Variables
Conclusion du Module
Ce que Vous Avez Appris
✅ Risques des secrets en clair : Statistiques alarmantes, exemples réels
✅ Ansible Vault : Chiffrement AES-256 pour fichiers et variables
✅ Files vs Strings : Chiffrement complet vs inline (!vault |)
✅ Commandes Vault : create, edit, view, encrypt, decrypt, encrypt_string
✅ Gestion mots de passe : --ask-vault-pass, .vault_pass, scripts, CI/CD
✅ Intégration playbooks : vars_files, variables inline chiffrées
✅ Déploiement sécurisé : MySQL avec credentials chiffrés
Commandes Clés à Retenir
# Créer un fichier chiffré
ansible-vault create secrets.yml
# Éditer un fichier chiffré
ansible-vault edit secrets.yml
# Visualiser un fichier chiffré
ansible-vault view secrets.yml
# Chiffrer un fichier existant
ansible-vault encrypt secrets.yml
# Déchiffrer un fichier
ansible-vault decrypt secrets.yml
# Chiffrer une variable inline
ansible-vault encrypt_string 'MySecret' --name 'my_var'
# Exécuter avec mot de passe
ansible-playbook site.yml --ask-vault-pass
# Exécuter avec fichier
ansible-playbook site.yml --vault-password-file .vault_pass
# Changer le mot de passe Vault
ansible-vault rekey secrets.yml
Best Practices Sécurité
1. Toujours chiffrer les secrets
# ❌ JAMAIS
mysql_password: SuperSecret123
# ✅ TOUJOURS
mysql_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
...
2. .vault_pass dans .gitignore
3. Permissions strictes
4. Rotation des secrets
5. Audit des accès
# Logger qui accède aux secrets (CI/CD)
echo "$(date) - $USER - Accessed vault" >> /var/log/vault_access.log
6. Ne jamais logger les secrets
7. Séparer les environnements
secrets/
├── dev_secrets.yml # Vault password: DevPass123
├── staging_secrets.yml # Vault password: StagingPass456
└── prod_secrets.yml # Vault password: ProdPass789Secure!
Chaque environnement = mot de passe Vault différent
Différence Vault vs Gestionnaires de Secrets
| Aspect | Ansible Vault | HashiCorp Vault / AWS Secrets Manager |
|---|---|---|
| Scope | Fichiers Ansible | Toute l'infrastructure |
| Centralisation | ❌ Fichiers locaux | ✅ Serveur centralisé |
| Rotation auto | ❌ Manuelle | ✅ Automatique |
| Audit détaillé | ⚠️ Git commits | ✅ Logs complets |
| Accès dynamique | ❌ Fichiers statiques | ✅ Secrets générés à la demande |
| Complexité | ✅ Simple | ⚠️ Infrastructure supplémentaire |
| Coût | ✅ Gratuit | ⚠️ Payant (AWS/Azure) ou self-hosted |
Règle d'or :
- < 10 serveurs : Ansible Vault suffit
- > 10 serveurs : Envisager HashiCorp Vault
Intégration HashiCorp Vault (Aperçu)
Pour infrastructures avancées :
# Récupérer un secret depuis HashiCorp Vault
- name: Obtenir le mot de passe DB
set_fact:
mysql_password: "{{ lookup('hashi_vault', 'secret=secret/data/mysql:password') }}"
Avantages :
- ✅ Secrets jamais stockés dans Ansible
- ✅ Rotation automatique
- ✅ Audit complet (qui/quand/quoi)
- ✅ Accès révocables dynamiquement
Module suivant potentiel : Intégration HashiCorp Vault
Prochaines Étapes
Module 5 (optionnel) : Testing & CI/CD
- Molecule (tests automatisés de rôles)
- Ansible Lint (validation best practices)
- Intégration GitLab CI / GitHub Actions
- Pipeline complet : Lint → Test → Deploy
TP Final Ansible Mastery (potentiel) :
- Déploiement application 3-tiers complète
- Rôles (common, web, db, monitoring)
- Secrets avec Vault
- Templates Jinja2
- CI/CD avec GitLab
Ressources Complémentaires
Documentation officielle :
Outils recommandés :
- git-secrets : Prevent committing secrets
- truffleHog : Scan Git history for secrets
- GitGuardian : Monitor public repos for leaks
- 1Password / Bitwarden : Team password managers
Checklist pré-production :
- [ ] Tous les secrets chiffrés avec Vault
- [ ]
.vault_passdans.gitignore - [ ] Aucun secret en clair dans Git history
- [ ] Permissions 600 sur fichiers sensibles
- [ ] Mot de passe Vault complexe (16+ caractères)
- [ ] Rotation planifiée (90 jours)
- [ ] Backup du mot de passe Vault (1Password/Bitwarden)
- [ ] Documentation des secrets (quoi/où sans révéler valeurs)
Félicitations ! Vous maîtrisez Ansible Vault et pouvez déployer des infrastructures sécurisées avec des secrets chiffrés, conformes aux standards DevSecOps et SecNumCloud. 🎉🔒
La formation Ansible Mastery est maintenant complète ! Vous êtes prêt à gérer des infrastructures à grande échelle avec automatisation, réutilisabilité et sécurité.
Navigation
| ← Module 3 : Roles & Templates - L'Indu... | TP Final : Infrastructure Multi-Tier ... → |