1. Organiser un projet Ansible #
De quelques fichiers à un dépôt industrialisé.
Structure de référence #
projet-infra/
├── ansible.cfg
├── requirements.yml
├── site.yml # point d'entrée : importe les playbooks
├── playbooks/
│ ├── loadbalancers.yml
│ ├── webservers.yml
│ └── dbservers.yml
├── inventories/
│ ├── lab/ {hosts.ini, group_vars/, host_vars/}
│ └── prod/ {hosts.ini, group_vars/, host_vars/}
└── roles/
├── common/ nginx/ haproxy/ postgresql/# site.yml
- import_playbook: playbooks/dbservers.yml
- import_playbook: playbooks/webservers.yml
- import_playbook: playbooks/loadbalancers.yml2. Un playbook de production #
Variables, handlers, tags et conditions.
Exemple complet #
# playbooks/webservers.yml
- name: Configurer les serveurs web
hosts: webservers
become: true
gather_facts: true
vars:
app_version: "1.4.2"
roles:
- role: common
tags: [common]
- role: nginx
tags: [nginx]
pre_tasks:
- name: Retirer le serveur du load balancer
ansible.builtin.uri:
url: "http://lb.lab:8404/disable/{{ inventory_hostname }}"
method: POST
delegate_to: localhost
tasks:
- name: Déployer l'application
ansible.builtin.unarchive:
src: "https://artifacts.lab/app-{{ app_version }}.tgz"
dest: /opt/app
remote_src: true
notify: Redémarrer l'application
tags: [deploy]
post_tasks:
- name: Vérifier que l'application répond
ansible.builtin.uri:
url: "http://localhost:8080/health"
status_code: 200
retries: 10
delay: 3
register: health
until: health.status == 200
handlers:
- name: Redémarrer l'application
ansible.builtin.systemd:
name: app
state: restartedExécuter, simuler, cibler #
ansible-playbook site.yml --syntax-check
ansible-playbook site.yml --check --diff # dry-run + différences
ansible-playbook site.yml -i inventories/prod --limit web1.lab
ansible-playbook site.yml --tags deploy
ansible-playbook site.yml --skip-tags common
ansible-playbook site.yml --start-at-task "Déployer l'application"
ansible-playbook site.yml -vvv # débogage détaillé
ansible-playbook site.yml --list-hosts --list-tasks3. Déploiements progressifs et résilients #
serial, blocs et gestion des erreurs.
Rolling update avec serial #
- hosts: webservers
serial: "25%" # ou 2, ou [1, 5, 10] pour des vagues croissantes
max_fail_percentage: 10 # arrêter si plus de 10 % des hôtes échouent
tasks:
- name: Mettre à jour l'application
ansible.builtin.package: { name: app, state: latest }Bonne Pratique : Avec serial, les vagues se déroulent l'une après l'autre : une erreur sur la première vague empêche de propager un mauvais déploiement à toute la production.block / rescue / always #
- name: Déploiement avec retour arrière
block:
- name: Appliquer la nouvelle version
ansible.builtin.command: /opt/app/deploy.sh {{ app_version }}
- name: Smoke test
ansible.builtin.uri: { url: "http://localhost:8080/health" }
rescue:
- name: Restaurer la version précédente
ansible.builtin.command: /opt/app/rollback.sh
- name: Notifier l'équipe
community.general.slack: { token: "{{ vault_slack_token }}", msg: "Déploiement échoué sur {{ inventory_hostname }}" }
delegate_to: localhost
always:
- name: Journaliser l'opération
ansible.builtin.lineinfile: { path: /var/log/deploys.log, line: "{{ ansible_date_time.iso8601 }} {{ app_version }}", create: true }Délégation et exécution unique #
- name: Migrer le schéma (une seule fois pour tout le groupe)
ansible.builtin.command: /opt/app/migrate.sh
run_once: true
delegate_to: "{{ groups['dbservers'][0] }}"
- name: Enregistrer le déploiement dans le CMDB
ansible.builtin.uri: { url: "https://cmdb.lab/api/deployments", method: POST, body_format: json, body: { host: "{{ inventory_hostname }}" } }
delegate_to: localhostErreur Courante :commandetshellne sont pas idempotents : ajoutezcreates:,removes:ouchanged_when:pour que le playbook reste rejouable.
Mon suivi
Connectez-vous pour suivre votre progression et prendre des notes. Se connecter
Articles recommandés
Linux vs Unix : Le Guide Complet des Commandes et Distributions
Comprenez les différences entre Linux et Unix, explorez les distributions (serveur, desktop, ligh...
Ansible : l'inventaire (statique, dynamique, groupes et variables)
Comprendre et maîtriser l'inventaire Ansible : fichiers INI et YAML, groupes, variables d'hôte et...
Ansible : les commandes Ad-Hoc
Exécuter des actions immédiates sur un parc de serveurs avec ansible : modules ping, command, she...
Ansible : structurer son code avec les rôles
Créer, organiser et réutiliser des rôles Ansible : arborescence, defaults, tasks, handlers, templ...
Ansible : générer des fichiers dynamiques avec Jinja2 et les facts
Créer des fichiers de configuration dynamiques : templates Jinja2, variables, facts, filtres, bou...
Ansible : gérer la sécurité (Vault, SSH, privilèges et secrets)
Sécuriser Ansible : Ansible Vault, authentification SSH par clés, become et sudo, no_log, durciss...
Ansible : piloter ses automatisations avec une interface graphique (AWX, Semaphore, AAP)
Comparer et installer les interfaces graphiques d'Ansible : AWX, Ansible Automation Platform, Sem...
Ansible : aller plus loin (tests, qualité, CI/CD et performance)
Industrialiser Ansible : ansible-lint, yamllint, Molecule, intégration continue, collections, exe...
Bonnes pratiques Vagrant : des environnements reproductibles et rapides
Bonnes pratiques Vagrant : Vagrantfile versionné, boxes épinglées, provisioning idempotent, multi...