
Un rôle Ansible suit une structure de dossiers stricte définie par la communauté et appliquée par ansible-galaxy role init. Cette convention rend les rôles prévisibles : peu importe qui a écrit le rôle, vous savez où chercher quoi (tâches, variables, templates, handlers). Connaître cette structure est mandatory au RHCE EX294.
Cette page passe en revue les 10 dossiers d’un rôle, quoi mettre dans chacun, les anti-patterns à éviter, et la convention de nommage des fichiers.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Générer un rôle vierge avec
ansible-galaxy role init. - Identifier les 10 dossiers d’un rôle et leur fonction précise.
- Comprendre la différence
defaults/vsvars/(objectif RHCE explicite). - Savoir où placer templates, fichiers statiques, modules custom.
- Documenter un rôle avec
README.mdetmeta/argument_specs.yml.
Prérequis
Section intitulée « Prérequis »- Avoir lu Découvrir les rôles.
- Avoir Ansible installé (
ansible --versiondoit fonctionner).
Générer la structure avec ansible-galaxy
Section intitulée « Générer la structure avec ansible-galaxy »Plutôt que créer les dossiers à la main, utiliser ansible-galaxy role init :
ansible-galaxy role init nginxSortie :
- Role nginx was created successfullyArborescence générée :
Répertoirenginx/
Répertoiredefaults/
- main.yml
Répertoirefiles/
- …
Répertoirehandlers/
- main.yml
Répertoiremeta/
- main.yml
Répertoiretasks/
- main.yml
Répertoiretemplates/
- …
Répertoiretests/
- inventory
- test.yml
Répertoirevars/
- main.yml
- README.md
8 dossiers + 2 fichiers racine. La structure est immédiatement utilisable. Vous pouvez aussi utiliser --init-path roles/ pour générer dans un dossier spécifique.
Les 10 dossiers en détail
Section intitulée « Les 10 dossiers en détail »tasks/ — le cœur du rôle
Section intitulée « tasks/ — le cœur du rôle »C’est ici que vivent les tâches Ansible qui composent le rôle. Le fichier d’entrée est tasks/main.yml — exécuté automatiquement quand le rôle est appelé.
---- name: Installer nginx ansible.builtin.dnf: name: nginx state: present notify: Restart nginx
- name: Démarrer nginx ansible.builtin.systemd_service: name: nginx state: started enabled: truePour les rôles complexes, vous pouvez splitter en plusieurs fichiers et les inclure depuis main.yml :
---- name: Inclure les tâches d'installation ansible.builtin.include_tasks: install.yml
- name: Inclure les tâches de configuration ansible.builtin.include_tasks: configure.yml when: nginx_configure | default(true)Avec :
Répertoiretasks/
- main.yml ← orchestrateur
- install.yml ← installation paquets
- configure.yml ← config files
- secure.yml ← durcissement (optionnel)
defaults/main.yml — variables par défaut (priorité faible)
Section intitulée « defaults/main.yml — variables par défaut (priorité faible) »Variables avec des valeurs par défaut que l’utilisateur du rôle peut override. Niveau de précédence le plus faible (priorité 2 sur 22 dans la précédence Ansible).
---nginx_version: "1.26.1"nginx_user: nginxnginx_workers: 4nginx_port: 80nginx_ssl_enabled: falseConvention forte : préfixer les variables avec le nom du rôle (nginx_ ici). Évite les collisions quand plusieurs rôles partagent une variable comme version ou port.
vars/main.yml — variables internes (priorité haute)
Section intitulée « vars/main.yml — variables internes (priorité haute) »Variables que l’utilisateur du rôle ne doit PAS modifier. Niveau de précédence haut (priorité 18 sur 22). Typiquement : chemins système, mappings OS, constantes.
---nginx_config_dir: /etc/nginxnginx_log_dir: /var/log/nginxnginx_pid_file: /run/nginx.pid
# Mapping nom de paquet selon la distrib__nginx_packages: RedHat: - nginx Debian: - nginx - nginx-extrasConvention : préfixer par _ ou __ les variables internes (__nginx_packages) pour signaler qu’elles ne doivent pas être manipulées de l’extérieur.
handlers/main.yml — actions réactives
Section intitulée « handlers/main.yml — actions réactives »Handlers déclenchés par notify: dans les tâches. S’exécutent à la fin du play, uniquement si notifiés.
---- name: Restart nginx ansible.builtin.systemd_service: name: nginx state: restarted
- name: Reload nginx ansible.builtin.systemd_service: name: nginx state: reloadedConvention : nommer les handlers en anglais avec verbe d’action (Restart nginx, Reload haproxy). Pas de noms cryptiques.
templates/ — fichiers Jinja2
Section intitulée « templates/ — fichiers Jinja2 »Templates Jinja2 rendus côté control node puis transférés sur la cible. Convention d’extension : .j2.
templates/├── nginx.conf.j2├── site.conf.j2└── ssl.conf.j2Référencés dans les tâches :
- name: Déployer nginx.conf ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf mode: "0644" notify: Reload nginxPas besoin de chemin absolu : Ansible cherche d’abord dans <role>/templates/, puis ailleurs si non trouvé.
files/ — fichiers statiques
Section intitulée « files/ — fichiers statiques »Fichiers à transférer tels quels (sans rendu Jinja). Pour des configs qui ne dépendent d’aucune variable.
files/├── motd ← fichier MOTD statique├── ssl-dhparams.pem ← certificat└── logo.png ← imageRéférencés via le module copy :
- name: Déployer le MOTD ansible.builtin.copy: src: motd ← Ansible cherche dans <role>/files/ dest: /etc/motd mode: "0644"Différence avec templates/ : files/ = inchangé, templates/ = rendu Jinja avec variables.
meta/main.yml — metadata du rôle
Section intitulée « meta/main.yml — metadata du rôle »Carte d’identité du rôle pour Ansible Galaxy et les dépendances.
---galaxy_info: author: Stéphane Robert namespace: stephrobert role_name: nginx description: Installer et configurer nginx license: MIT min_ansible_version: "2.16" platforms: - name: EL versions: - "9" - "10" - name: Debian versions: - bookworm - name: Ubuntu versions: - jammy galaxy_tags: - nginx - webserver
dependencies: - role: stephrobert.firewalld version: ">=1.0.0"Champs essentiels :
role_name+namespace: identifiant Galaxy.min_ansible_version: version mini d’Ansible requise.platforms: OS supportés — l’utilisateur saura si le rôle marche chez lui.dependencies: autres rôles à installer en cascade.
meta/argument_specs.yml — validation des variables (RECOMMANDÉ 2026)
Section intitulée « meta/argument_specs.yml — validation des variables (RECOMMANDÉ 2026) »Depuis Ansible 2.11, argument_specs.yml valide automatiquement les variables d’entrée du rôle. Mandatory pour un rôle de qualité.
---argument_specs: main: short_description: "Installer et configurer nginx" options: nginx_version: type: str default: "1.26.1" description: "Version de nginx à installer" nginx_workers: type: int default: 4 description: "Nombre de worker_processes" nginx_ssl_enabled: type: bool default: false description: "Activer HTTPS" nginx_listen_port: type: int default: 80 description: "Port d'écoute HTTP" choices: [80, 8080, 8000]Avantages :
- Erreur immédiate si l’utilisateur passe une mauvaise valeur.
- Documentation auto-générée via
ansible-doc --type role <role>. - Pas besoin d’écrire des
assert:à la main pour valider.
Couvert en détail dans la page argument_specs.yml.
library/ — modules Python custom (rare)
Section intitulée « library/ — modules Python custom (rare) »Si votre rôle nécessite un module Ansible custom (qui n’existe pas dans une collection), placez-le ici.
library/└── my_custom_module.pyLe module devient utilisable immédiatement dans les tasks du rôle, sans déclaration FQCN. Cas d’usage rare — préférer écrire une collection plutôt qu’un module isolé.
filter_plugins/ — filtres Jinja custom (rare)
Section intitulée « filter_plugins/ — filtres Jinja custom (rare) »Filtres Jinja personnalisés pour transformer des données dans les templates.
def my_uppercase(value): return value.upper()
class FilterModule: def filters(self): return {'my_uppercase': my_uppercase}Utilisable dans un template du rôle : {{ my_string | my_uppercase }}. Cas d’usage rare également.
tests/ — tests Molecule (recommandé)
Section intitulée « tests/ — tests Molecule (recommandé) »Tests Molecule du rôle. La convention 2026 :
molecule/└── default/ ├── molecule.yml ← config du scénario ├── converge.yml ← playbook qui appelle le rôle └── verify.yml ← assertions à validerCouvert en détail dans la page Cycle TDD avec Molecule.
README.md — documentation (mandatory)
Section intitulée « README.md — documentation (mandatory) »Documentation principale du rôle. Mandatory pour publier sur Galaxy.
Structure recommandée :
# Rôle nginx
Installe et configure nginx sur RHEL 9/10, Debian 12, Ubuntu 24.04.
## Variables
| Variable | Défaut | Description ||---|---|---|| `nginx_version` | "1.26.1" | Version à installer || `nginx_workers` | 4 | Nombre de worker_processes |
## Exemple d'utilisation
\`\`\`yaml- hosts: webservers roles: - role: nginx vars: nginx_workers: 8\`\`\`
## Tests
\`\`\`bashmolecule test\`\`\`
## Licence
MITArborescence complète d’un rôle de production
Section intitulée « Arborescence complète d’un rôle de production »Voici l’arborescence d’un rôle nginx mature avec TOUS les éléments que vous pouvez rencontrer :
Répertoirenginx/
Répertoiredefaults/
- main.yml ← variables par défaut (override possibles)
Répertoirevars/
- main.yml ← variables internes (NE PAS modifier)
- RedHat.yml ← variables spécifiques RHEL
- Debian.yml ← variables spécifiques Debian
Répertoiretasks/
- main.yml ← orchestrateur
- install.yml ← installation paquets
- configure.yml ← config files
- secure.yml ← durcissement TLS
Répertoirehandlers/
- main.yml ← Restart nginx, Reload nginx
Répertoiretemplates/
- nginx.conf.j2
- site.conf.j2
Répertoirefiles/
- ssl-dhparams.pem
Répertoiremeta/
- main.yml ← Galaxy info
- argument_specs.yml ← validation variables
Répertoiremolecule/
Répertoiredefault/
- molecule.yml
- converge.yml
- verify.yml
- .ansible-lint ← config linter
- .yamllint ← config yamllint
- tox.ini ← tests multi-versions Ansible
- README.md ← documentation
- LICENSE
- CHANGELOG.md ← historique des versions
- .gitignore
Pièges courants
Section intitulée « Pièges courants »| Symptôme | Cause | Fix |
|---|---|---|
| Variables ignorées par l’utilisateur | Définies dans vars/ au lieu de defaults/ | vars/ = priorité 18 (haute), bouger vers defaults/ (priorité 2) |
Cannot find role 'nginx' | Rôle pas dans roles_path | Vérifier ansible.cfg → roles_path |
| Handler ne se déclenche pas | Pas de notify: ou nom de handler erroné | Vérifier que le notify: correspond exactement au name: du handler |
| Fichier template non trouvé | Mauvais chemin (Ansible cherche dans <role>/templates/) | Pas de chemin absolu : src: nginx.conf.j2 (sans templates/) |
ansible-doc --type role <role> échoue | Pas de meta/argument_specs.yml | Créer le fichier avec au moins le main: minimal |
À retenir
Section intitulée « À retenir »ansible-galaxy role init <nom>génère la structure standard automatiquement.- 10 dossiers types : tasks, defaults, vars, handlers, templates, files, meta, library, filter_plugins, tests.
defaults/= override possible.vars/= constantes internes. Convention RHCE.- Préfixer les variables avec le nom du rôle (
nginx_version) pour éviter les collisions. meta/main.yml= carte d’identité Galaxy.meta/argument_specs.yml= validation auto.tests/legacy →molecule/moderne en 2026.README.mdmandatory pour publier.