Aller au contenu
English
English
Infrastructure as Code medium

Structure standard d'un rôle Ansible : 10 dossiers et leur rôle

55 min de lecture

Logo Ansible

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.

  • 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/ vs vars/ (objectif RHCE explicite).
  • Savoir où placer templates, fichiers statiques, modules custom.
  • Documenter un rôle avec README.md et meta/argument_specs.yml.

Plutôt que créer les dossiers à la main, utiliser ansible-galaxy role init :

Fenêtre de terminal
ansible-galaxy role init nginx

Sortie :

- Role nginx was created successfully

Arborescence 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.

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.

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é.

tasks/main.yml
---
- 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: true

Pour les rôles complexes, vous pouvez splitter en plusieurs fichiers et les inclure depuis main.yml :

tasks/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).

defaults/main.yml
---
nginx_version: "1.26.1"
nginx_user: nginx
nginx_workers: 4
nginx_port: 80
nginx_ssl_enabled: false

Convention 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.

vars/main.yml
---
nginx_config_dir: /etc/nginx
nginx_log_dir: /var/log/nginx
nginx_pid_file: /run/nginx.pid
# Mapping nom de paquet selon la distrib
__nginx_packages:
RedHat:
- nginx
Debian:
- nginx
- nginx-extras

Convention : préfixer par _ ou __ les variables internes (__nginx_packages) pour signaler qu'elles ne doivent pas être manipulées de l'extérieur.

Handlers déclenchés par notify: dans les tâches. S'exécutent à la fin du play, uniquement si notifiés.

handlers/main.yml
---
- name: Restart nginx
ansible.builtin.systemd_service:
name: nginx
state: restarted
- name: Reload nginx
ansible.builtin.systemd_service:
name: nginx
state: reloaded

Convention : nommer les handlers en anglais avec verbe d'action (Restart nginx, Reload haproxy). Pas de noms cryptiques.

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.j2

Ré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 nginx

Pas besoin de chemin absolu : Ansible cherche d'abord dans <role>/templates/, puis ailleurs si non trouvé.

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 ← image

Ré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.

Carte d'identité du rôle pour Ansible Galaxy et les dépendances.

meta/main.yml
---
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é.

meta/argument_specs.yml
---
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.

Si votre rôle nécessite un module Ansible custom (qui n'existe pas dans une collection), placez-le ici.

library/
└── my_custom_module.py

Le 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é.

Filtres Jinja personnalisés pour transformer des données dans les templates.

filter_plugins/my_filters.py
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 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 à valider

Couvert en détail dans la page Cycle TDD avec Molecule.

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
\`\`\`bash
molecule test
\`\`\`
## Licence
MIT

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

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ômeCauseFix
Variables ignorées par l'utilisateurDé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_pathVérifier ansible.cfg → roles_path
Handler ne se déclenche pasPas 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> échouePas de meta/argument_specs.ymlCréer le fichier avec au moins le main: minimal

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

6 questions
6 min.
70% requis

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

  • 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.md mandatory pour publier.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn