Playbooks Ansible
Objectifs du chapitre
- Comprendre la structure d'un playbook
- Écrire des playbooks YAML
- Utiliser les handlers et les conditions
- Organiser des playbooks complexes
1 - Qu'est-ce qu'un playbook ?
Définition
Un playbook est un fichier YAML décrivant une série de tâches à exécuter sur des hôtes.
Structure de base
---
# site.yml - Mon premier playbook
- name: Configurer les serveurs web
hosts: webservers
become: yes
tasks:
- name: Installer nginx
apt:
name: nginx
state: present
- name: Démarrer nginx
service:
name: nginx
state: started
enabled: yes
2 - Anatomie d'un playbook
Composants
Éléments d'un play
| Élément | Description | Obligatoire |
|---|---|---|
name | Description du play | Non (recommandé) |
hosts | Hôtes cibles | Oui |
become | Escalade privilèges | Non |
vars | Variables | Non |
tasks | Liste des tâches | Oui |
handlers | Tâches déclenchées | Non |
Éléments d'une tâche
tasks:
- name: Description de la tâche # Obligatoire (bonne pratique)
module_name: # Module à utiliser
param1: value1 # Arguments du module
param2: value2
become: yes # Options de la tâche
when: condition # Condition
notify: handler_name # Déclencher un handler
register: result # Capturer le résultat
3 - Exemple complet
Playbook serveur web
---
# webserver.yml
- name: Configuration complète serveur web
hosts: webservers
become: yes
vars:
http_port: 80
domain: example.com
tasks:
- name: Mettre à jour le cache apt
apt:
update_cache: yes
cache_valid_time: 3600
- name: Installer les packages requis
apt:
name:
- nginx
- certbot
- python3-certbot-nginx
state: present
- name: Créer le répertoire web
file:
path: /var/www/{{ domain }}
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Copier la configuration nginx
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/sites-available/{{ domain }}
notify: Reload nginx
- name: Activer le site
file:
src: /etc/nginx/sites-available/{{ domain }}
dest: /etc/nginx/sites-enabled/{{ domain }}
state: link
notify: Reload nginx
- name: S'assurer que nginx est démarré
service:
name: nginx
state: started
enabled: yes
handlers:
- name: Reload nginx
service:
name: nginx
state: reloaded
4 - Handlers
Concept
Les handlers sont des tâches déclenchées uniquement si une tâche les notifie.
Syntaxe
tasks:
- name: Copier la configuration
copy:
src: app.conf
dest: /etc/app/app.conf
notify:
- Restart app
- Clear cache
handlers:
- name: Restart app
service:
name: myapp
state: restarted
- name: Clear cache
command: /usr/local/bin/clear-cache.sh
Forcer l'exécution des handlers
tasks:
- name: Copier la configuration
copy:
src: app.conf
dest: /etc/app/app.conf
notify: Restart app
- name: Forcer l'exécution des handlers maintenant
meta: flush_handlers
- name: Vérifier que l'app fonctionne
uri:
url: http://localhost:8080/health
5 - Conditions (when)
Syntaxe de base
tasks:
- name: Installer sur Debian
apt:
name: nginx
when: ansible_os_family == "Debian"
- name: Installer sur RedHat
yum:
name: nginx
when: ansible_os_family == "RedHat"
Opérateurs
tasks:
# Égalité
- name: Si Ubuntu
debug:
msg: "C'est Ubuntu"
when: ansible_distribution == "Ubuntu"
# Comparaison
- name: Si version >= 20.04
debug:
msg: "Version récente"
when: ansible_distribution_version is version('20.04', '>=')
# ET logique
- name: Ubuntu 22.04
debug:
msg: "Ubuntu 22.04"
when:
- ansible_distribution == "Ubuntu"
- ansible_distribution_version == "22.04"
# OU logique
- name: Debian ou Ubuntu
debug:
msg: "Famille Debian"
when: ansible_distribution == "Debian" or ansible_distribution == "Ubuntu"
# Négation
- name: Pas RedHat
debug:
msg: "Pas RedHat"
when: ansible_os_family != "RedHat"
# Variable définie
- name: Si variable existe
debug:
msg: "Variable définie"
when: my_variable is defined
# Dans une liste
- name: Si dans la liste
debug:
msg: "Package supporté"
when: package_name in ['nginx', 'apache2', 'lighttpd']
Conditions avec register
tasks:
- name: Vérifier si le fichier existe
stat:
path: /etc/myapp/config.yml
register: config_file
- name: Créer le fichier si absent
copy:
content: "# Configuration par défaut"
dest: /etc/myapp/config.yml
when: not config_file.stat.exists
6 - Boucles (loop)
loop simple
tasks:
- name: Créer plusieurs utilisateurs
user:
name: "{{ item }}"
state: present
loop:
- alice
- bob
- charlie
- name: Installer plusieurs packages
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- postgresql
- redis
loop avec dictionnaires
tasks:
- name: Créer utilisateurs avec détails
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
shell: "{{ item.shell | default('/bin/bash') }}"
loop:
- { name: 'alice', groups: 'developers', shell: '/bin/zsh' }
- { name: 'bob', groups: 'admins' }
- { name: 'charlie', groups: 'developers' }
loop avec index
tasks:
- name: Créer des fichiers numérotés
copy:
content: "Fichier numéro {{ my_idx + 1 }}"
dest: "/tmp/file{{ my_idx + 1 }}.txt"
loop:
- first
- second
- third
loop_control:
index_var: my_idx
7 - Variables dans les playbooks
Définir des variables
---
- name: Exemple avec variables
hosts: webservers
vars:
http_port: 80
app_name: myapp
packages:
- nginx
- php-fpm
- php-mysql
tasks:
- name: Afficher les variables
debug:
msg: "App {{ app_name }} sur port {{ http_port }}"
- name: Installer les packages
apt:
name: "{{ packages }}"
state: present
Variables depuis fichiers
---
- name: Avec fichier de variables
hosts: webservers
vars_files:
- vars/common.yml
- vars/{{ ansible_os_family }}.yml
tasks:
- name: Utiliser les variables
debug:
var: some_variable
Prompt interactif
---
- name: Avec prompt
hosts: webservers
vars_prompt:
- name: admin_password
prompt: "Mot de passe admin?"
private: yes
tasks:
- name: Créer l'admin
user:
name: admin
password: "{{ admin_password | password_hash('sha512') }}"
8 - Register et debug
Capturer les résultats
tasks:
- name: Exécuter une commande
command: cat /etc/os-release
register: os_info
- name: Afficher le résultat
debug:
var: os_info.stdout_lines
- name: Afficher si succès
debug:
msg: "Commande réussie"
when: os_info.rc == 0
Structure d'un résultat
9 - Tags
Ajouter des tags
tasks:
- name: Installer nginx
apt:
name: nginx
tags:
- packages
- nginx
- name: Configurer nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
tags:
- configuration
- nginx
- name: Démarrer nginx
service:
name: nginx
state: started
tags:
- services
- nginx
Exécuter avec tags
# Exécuter seulement les tâches nginx
ansible-playbook site.yml --tags nginx
# Exécuter seulement les packages
ansible-playbook site.yml --tags packages
# Exclure des tags
ansible-playbook site.yml --skip-tags configuration
# Lister les tags disponibles
ansible-playbook site.yml --list-tags
10 - Organisation des playbooks
Inclure d'autres playbooks
# site.yml - Playbook principal
---
- import_playbook: playbooks/webservers.yml
- import_playbook: playbooks/databases.yml
- import_playbook: playbooks/loadbalancers.yml
Inclure des tâches
# main.yml
tasks:
- name: Tâches communes
include_tasks: tasks/common.yml
- name: Tâches spécifiques OS
include_tasks: "tasks/{{ ansible_os_family }}.yml"
Résumé
Points clés
- Les playbooks sont des fichiers YAML
- Chaque tâche doit avoir un nom descriptif
- Utilisez les handlers pour les actions post-changement
- Les conditions
whenpermettent la logique conditionnelle - Les tags facilitent l'exécution partielle
Exercices pratiques
- Créez un playbook qui installe et configure nginx
- Ajoutez des handlers pour recharger le service
- Utilisez des conditions pour gérer différents OS
- Organisez avec des tags et des includes