
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 »ansible-galaxy role init en génère huit, et deux autres se créent à la main quand le besoin se présente. Chacun a un rôle unique, et c'est cette convention qui permet à Ansible de trouver un gabarit ou un handler sans qu'aucun chemin soit écrit dans les tâches. Les sections qui suivent les prennent dans l'ordre d'importance, du plus employé au plus rare.
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 :
Le répertoire tests/ généré par ansible-galaxy role init date d'une époque où l'on testait un rôle en jouant un playbook à la main sur un inventaire bidon. Il reste dans la structure par compatibilité, et rien n'oblige à le remplir. Molecule a repris ce travail avec un répertoire à lui, molecule/default/, qui décrit la plateforme de test, le playbook de convergence et les assertions de vérification.
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.
Le README.md est la première chose que lit qui découvre le rôle, et souvent la seule. Il répond à trois questions dans cet ordre : ce que le rôle fait, quelles variables il attend avec leurs valeurs par défaut, et à quoi ressemble un appel complet. Depuis que meta/argument_specs.yml existe, la liste des variables peut être générée plutôt que recopiée, ce qui évite qu'elle vieillisse.
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 »Quatre de ces symptômes tiennent au mauvais répertoire : une variable rangée dans vars/ quand elle devait être surchargeable, un gabarit posé hors de templates/, un fichier de tâches que rien n'inclut. Le cinquième vient de la casse d'un nom de handler, qui se compare à la lettre près et échoue en silence.
| 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 |
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À 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.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Variables : defaults contre vars : deux dossiers de cette structure, deux priorités opposées dans la précédence.
- Handlers et meta : ce qu'on écrit dans
handlers/et dansmeta/main.yml, et pourquoi. - argument_specs.yml : le fichier de
meta/qui valide les entrées du rôle avant la première tâche.