
Tâches (Tasks), Jeux (Plays), Playbooks : orchestrer les actions
Comprenez la hiérarchie Tasks, Plays et Playbooks dans Ansible. Apprenez comment ces éléments s'articulent pour définir et exécuter des scénarios d'automatisation complexes et structurés sur votre infrastructure.
La structure de l'automatisation Ansible : des tâches aux playbooks
Si les modules Ansible sont les outils individuels, la véritable puissance de l'automatisation se révèle dans la manière dont ces outils sont assemblés et orchestrés pour accomplir des objectifs plus larges. Ansible utilise une hiérarchie claire pour structurer ces opérations : les tâches (Tasks) sont les actions unitaires, regroupées en jeux (Plays) qui ciblent des ensembles d'hôtes spécifiques, et l'ensemble de ces jeux constitue un playbook, le plan directeur de votre automatisation.
Comprendre cette structure est fondamental pour écrire des automatisations claires, maintenables et efficaces. Un playbook bien conçu est plus qu'une simple liste de commandes ; c'est une description logique et ordonnée de l'état désiré de votre infrastructure et des étapes pour y parvenir. Cette section décortique chacun de ces composants et montre comment ils s'articulent.
Les tâches (Tasks) : l'unité d'action fondamentale
Une tâche (Task) est l'unité d'action la plus élémentaire dans Ansible. Chaque tâche représente une invocation d'un module Ansible avec des paramètres spécifiques. L'objectif d'une tâche est de s'assurer qu'un aspect particulier d'un système est dans l'état désiré. Par exemple, une tâche peut consister à installer un paquet, une autre à copier un fichier, une troisième à démarrer un service.
Dans un playbook, les tâches sont définies sous la section `tasks:` d'un jeu. Elles sont exécutées séquentiellement, dans l'ordre où elles sont écrites, sur chaque hôte ciblé par le jeu. Voici un exemple de deux tâches :
tasks:
- name: Installer le paquet Apache
ansible.builtin.apt:
name: apache2
state: present
- name: S'assurer que le service Apache est démarré et activé
ansible.builtin.service:
name: apache2
state: started
enabled: yes
Chaque tâche possède généralement un attribut `name`, qui est une description lisible de ce que fait la tâche. Bien qu'optionnel, il est fortement recommandé de nommer ses tâches pour améliorer la lisibilité du playbook et faciliter le suivi lors de son exécution. La tâche elle-même est définie par le nom du module à utiliser (ici `ansible.builtin.apt` et `ansible.builtin.service`) et les paramètres passés à ce module.
Ansible offre de nombreuses fonctionnalités pour contrôler l'exécution des tâches, comme les conditions (`when`), les boucles (`loop`), la gestion des erreurs (`failed_when`, `changed_when`, `ignore_errors`), l'enregistrement des résultats dans des variables (`register`), et l'utilisation de handlers pour déclencher d'autres actions en réponse à un changement.
Les jeux (Plays) : cibler les actions et définir un contexte
Un jeu (Play) est un ensemble ordonné de tâches qui sont exécutées sur un groupe d'hôtes spécifique défini dans votre inventaire. Un playbook peut contenir un ou plusieurs jeux. Chaque jeu est une unité logique qui mappe un ensemble de machines à un ensemble d'actions à réaliser pour atteindre un état de configuration particulier sur ces machines.
Un jeu commence par spécifier les hôtes cibles via la directive `hosts`. Cela peut être un nom de groupe de l'inventaire, un pattern d'hôtes, ou `all` pour tous les hôtes. Un jeu peut également définir des variables (`vars`), des rôles (`roles` - une manière avancée de structurer le contenu Ansible), et la stratégie d'exécution (par exemple, `serial` pour exécuter sur un certain nombre d'hôtes à la fois).
Voici la structure d'un jeu simple :
- name: Configurer les serveurs web
hosts: webservers
become: yes # Exécuter les tâches en tant que root sur les cibles
vars:
http_port: 80
tasks:
- name: Installer Nginx
ansible.builtin.package:
name: nginx
state: present
- name: Configurer Nginx pour écouter sur le port {{ http_port }}
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx # Déclenche un handler
handlers:
- name: Restart Nginx
ansible.builtin.service:
name: nginx
state: restarted
Dans cet exemple, le jeu nommé "Configurer les serveurs web" s'applique à tous les hôtes du groupe `webservers`. Il définit une variable `http_port`, puis exécute deux tâches. La deuxième tâche utilise un template Jinja2 et notifie un `handler` nommé "Restart Nginx" si le fichier de configuration est modifié. Les handlers sont des tâches spéciales qui ne sont exécutées qu'une seule fois à la fin du jeu si elles ont été notifiées par une ou plusieurs tâches ayant entraîné un changement.
Les jeux sont exécutés séquentiellement dans l'ordre où ils apparaissent dans le playbook. Si un jeu échoue sur un hôte (c'est-à-dire qu'une tâche non ignorée échoue), Ansible arrête par défaut l'exécution des tâches restantes de ce jeu sur cet hôte. Le comportement global en cas d'échec peut être personnalisé.
Les playbooks : le scénario complet de votre automatisation
Un playbook Ansible est un fichier au format YAML qui contient un ou plusieurs jeux. C'est le niveau le plus élevé d'organisation pour vos instructions d'automatisation. Un playbook est conçu pour modéliser un processus complet, comme le déploiement d'une application, la configuration d'un environnement, ou la réalisation d'une mise à jour système à l'échelle de votre infrastructure.
Les playbooks sont le coeur de l'utilisation d'Ansible pour la gestion de configuration et l'orchestration. Ils permettent de décrire de manière explicite et versionnable l'état désiré de vos systèmes. Voici un exemple de playbook simple contenant un seul jeu (comme l'exemple précédent) :
---
- name: Configurer les serveurs web et déployer l'application
hosts: webservers
become: yes
vars_files:
- vars/main.yml
roles:
- common
- webserver
- app_deploy
tasks:
- name: Tâche additionnelle spécifique au playbook
ansible.builtin.debug:
msg: "Déploiement terminé sur {{ inventory_hostname }}"
post_tasks:
- name: Nettoyage final
ansible.builtin.file:
path: /tmp/deploy_files
state: absent
...
Ce playbook plus complet introduit d'autres concepts :
- `---` et `...` : Peuvent être utilisés pour délimiter le début et la fin d'un document YAML, utile si plusieurs documents sont dans un même fichier.
- `vars_files`: Permet de charger des variables depuis des fichiers externes.
- `roles`: Permet d'inclure des rôles Ansible. Les rôles sont un moyen puissant de structurer et de réutiliser des ensembles de tâches, variables, fichiers, templates et handlers. Ils favorisent la modularité et l'organisation de projets Ansible complexes. Un rôle typique pourrait être `nginx`, `mysql`, `security_hardening`, etc.
- `post_tasks`: Des tâches qui sont exécutées après toutes les tâches principales et les handlers du jeu, même si des tâches précédentes ont échoué (selon la configuration).
Pour exécuter un playbook, on utilise la commande `ansible-playbook` :
ansible-playbook -i mon_inventaire.ini mon_playbook.yml
Ansible va alors lire le playbook, l'interpréter, se connecter aux hôtes spécifiés dans chaque jeu, et exécuter les tâches dans l'ordre défini. La sortie de la commande `ansible-playbook` fournit un résumé des actions effectuées, indiquant pour chaque tâche si elle était `ok` (pas de changement, déjà conforme), `changed` (un changement a été effectué), `failed` (une erreur s'est produite), ou `skipped` (la tâche n'a pas été exécutée, par exemple à cause d'une condition `when`).
En combinant tâches, jeux et playbooks, vous pouvez construire des automatisations allant de la simple configuration d'un service à l'orchestration complexe de déploiements multi-tiers sur des centaines de serveurs.