Aller au contenu
Infrastructure as Code medium

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

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

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 :

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.

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
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.cfgroles_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
  • 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 +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn