Aller au contenu
Infrastructure as Code medium

Rôles Ansible : structure, TDD avec Molecule, tests testinfra et publication

12 min de lecture

Logo Ansible

Un rôle Ansible est l’unité de réutilisation par excellence : un dossier structuré qui regroupe tâches, variables, templates, handlers et tests autour d’un objectif unique (déployer nginx, configurer un firewall, créer des utilisateurs). Cette section couvre l’écriture professionnelle d’un rôle en 2026 : structure standard, développement piloté par les tests (TDD) avec Molecule, testinfra, tox, et publication sur Galaxy ou Automation Hub. Les rôles pèsent ~30 % de l’examen RHCE EX294 — c’est l’investissement pédagogique le plus rentable du parcours.

  • Structurer un rôle conforme aux conventions Ansible (10 dossiers types).
  • Écrire votre premier rôle en suivant le cycle TDD : test rouge → code → test vert.
  • Valider un rôle avec Molecule (Docker/Podman/Vagrant) sur plusieurs distros.
  • Écrire des tests Python avec testinfra (assertions plus expressives qu’Ansible).
  • Tester un rôle sur plusieurs versions d’Ansible avec tox.
  • Sécuriser les variables d’entrée avec meta/argument_specs.yml.
  • Publier un rôle sur Galaxy ou un Automation Hub privé.

Avant cette section, vous devez avoir validé :


Mon retour d’expérience — pour ceux qui veulent comprendre

Section intitulée « Mon retour d’expérience — pour ceux qui veulent comprendre »

Si l’une des cartes en haut de page vous a déjà orienté, vous êtes parti sur le bon pied. La suite de cette page s’adresse à ceux qui veulent comprendre la philosophie de cette section : pourquoi je pousse le TDD si tôt, pourquoi argument_specs.yml n’est pas négociable, pourquoi je préfère un rôle « ennuyeux » à un rôle « clever ».

J’ai écrit mon premier rôle Ansible en 2016 — sans tests, sans defaults, avec des command: partout. Il a tenu 6 mois avant de devenir intouchable : personne ne savait plus ce qu’il faisait, et le moindre changement cassait la prod. C’est cet incident qui m’a fait basculer vers Molecule, avant même que ce soit un standard Red Hat. Les sections qui suivent compilent les habitudes que je n’aurais jamais accepté de relâcher dans une équipe que je dirige — pas une revue théorique des fonctionnalités.

Un playbook unique de 500 lignes qui installe + configure + démarre nginx fonctionne mais devient vite ingérable :

  • Pas réutilisable : copier-coller dans le projet suivant, avec drift.
  • Pas testable isolément : impossible de tester nginx sans rejouer toute la stack.
  • Pas de séparation des responsabilités : tout est mélangé.
  • Pas paramétrable proprement : variables disséminées partout.

Un rôle résout ces 4 problèmes : code packagé, testable, paramétrable via defaults/, distribuable via Galaxy. C’est l’équivalent d’un module Terraform ou d’un chart Helm côté Ansible.

Le déclic TDD — pourquoi tester AVANT de coder ?

Section intitulée « Le déclic TDD — pourquoi tester AVANT de coder ? »

L’approche traditionnelle Ansible : on écrit le rôle, on lance, on regarde si ça marche. Problèmes :

  • Régressions : modifier un handler casse silencieusement le déploiement 6 mois plus tard.
  • Pas d’idempotence garantie : command: au lieu de modules dédiés, state: latest partout.
  • Couverture multi-distro inexistante : ça marche sur Ubuntu, plante sur RHEL.
  • Refactor risqué : on ne sait pas si la version 2 fait la même chose que la version 1.

L’approche TDD avec Molecule inverse le flux : on écrit d’abord le test dans verify.yml (test rouge car le rôle ne fait rien), puis on code le rôle jusqu’à ce que le test passe (vert). Bénéfices :

  • Spécification claire : le test décrit le comportement attendu avant l’implémentation.
  • Couverture intégrée : chaque feature a son test dès le départ.
  • Refactor sans peur : on modifie le code, on relance les tests, on sait si on a cassé quelque chose.
  • Multi-distro automatique : Molecule lance les tests sur Debian + RHEL + AlmaLinux en parallèle.

C’est exigeant au début mais transforme votre pratique durablement. Cette section l’enseigne dès la première écriture d’un rôle.

Cinq positions tranchées que cette section assume — chacune correspond à un combat que j’ai mené plusieurs fois en revue de code :

  • Un rôle = une responsabilité, pas trois. Le rôle webserver installe et configure nginx. Il ne crée pas l’utilisateur du site, ne pose pas le firewall, ne déploie pas le contenu. Chaque responsabilité = un rôle distinct, composable. Les rôles « tout-en-un » deviennent intouchables au bout de 6 mois.
  • Préfixe variable obligatoire (webserver_port, jamais port). Sans préfixe, deux rôles qui définissent port en defaults/ se marchent dessus selon l’ordre d’inclusion. Bug silencieux à diagnostiquer. Le préfixe est une assurance contre la collision, pas un caprice esthétique.
  • argument_specs.yml non négociable dès la version 1.0 du rôle. Sans lui, le rôle accepte n’importe quoi en entrée et plante au milieu du playbook avec un message obscur. Avec lui, l’utilisateur du rôle a une erreur claire avant même que la première tâche ne s’exécute. C’est aussi un objectif RHCE 2026.
  • TDD dès le premier rôle, pas « quand on aura le temps ». Ajouter Molecule à un rôle existant est 5× plus douloureux que partir avec dès le départ. Le coût d’apprentissage est concentré sur le premier rôle ; ensuite c’est un réflexe.
  • Un rôle ennuyeux est un bon rôle. Pas de Jinja2 imbriqué sur 5 niveaux, pas de set_fact dynamiques sophistiqués, pas de loop avec with_subelements quand un dict simple suffit. Le code que vous lirez à 2 h du matin doit être trivial. Le « clever » coûte cher en prod.

Cinq anti-patterns que cette section refuse — chacun causé par un raccourci qui semble malin sur le moment :

  • command: ou shell: quand un module dédié existe. Un junior écrit command: dnf install -y nginx — ça marche une fois, puis devient changed: true à chaque exécution, casse l’idempotence, et fait échouer le test Molecule. Cherchez toujours le module dédié : ansible.builtin.dnf, ansible.builtin.systemd_service, ansible.builtin.copy. Si vraiment aucun n’existe, command: avec creates: ou removes: pour préserver l’idempotence.
  • Variables critiques dans vars/ au lieu de defaults/. vars/main.yml a une précédence très haute que l’utilisateur du rôle ne peut pas surcharger facilement. Toute variable destinée à être paramétrée va dans defaults/main.yml ; vars/ est réservé aux constantes internes du rôle (chemins absolus de la distro, par exemple).
  • include_tasks partout au lieu de import_tasks. include est dynamique (résolu au runtime) — utile pour le looping, mais tags, when au niveau import, et --list-tasks ne fonctionnent pas comme attendu. Default = import_tasks (statique), include_tasks uniquement quand vous bouclez sur une liste avec loop:.
  • Rôle sans README.md. Un rôle qu’on ne sait pas configurer = un rôle qu’on ne réutilise pas = un rôle qu’on duplique. Le README.md doit lister toutes les variables d’entrée, leur type, leur valeur par défaut, et un exemple de playbook qui consomme le rôle. Sans ça, vous écrivez du code, pas un rôle.
  • Publication sans tag semver. requirements.yml peut épingler version: 1.2.3, mais si votre rôle n’a que des commits sur main, l’équipe en aval ne peut pas évoluer en confiance. Tag tous les changements impactants (v1.0.0, v1.1.0, v2.0.0) avec un changelog minimal — sinon votre rôle ne peut pas être adopté sérieusement.

Le parcours est séquentiel. Chaque phase suppose acquise la précédente.

Concepts fondamentaux : qu’est-ce qu’un rôle, quelle structure, où mettre quoi.

Premier rôle pratique avec lab — installer nginx, gérer les variables, ajouter handlers et validation.

Le cœur de cette section : adopter le développement piloté par les tests pour vos rôles.

Aller au-delà du verify.yml Ansible avec testinfra (Python), tox (multi-versions), CI/CD.

Consommer un rôle dans un playbook, gérer les dépendances, publier sur Galaxy.

Les rôles représentent environ 30 % de l’examen RHCE — c’est la plus grosse pondération après les modules. Les objectifs testés :

Objectif RHCEPage couvrante
Créer des rôlesCréer son premier rôle + Structure standard
Utiliser des rôles dans des playbooksConsommer un rôle
Télécharger depuis GalaxyInstaller des rôles depuis Galaxy
Argument specs (recommandé 2026)argument_specs.yml
Variables defaults/varsVariables : defaults vs vars
Handlers dans un rôleHandlers et meta

Les tests (Molecule, testinfra, tox) ne sont pas évalués au RHCE 2026, mais ils sont incontournables dans la vraie vie professionnelle. Cette section les enseigne dès le départ pour vous éviter d’apprendre Ansible « à l’ancienne » puis de devoir tout réapprendre ensuite.

OutilRôleQuand l’utiliser
ansible-lintLint statique du code AnsibleÀ chaque commit (pre-commit hook)
MoleculeFramework de test orchestréÀ chaque modification du rôle
verify.yml (Ansible)Tests d’état post-déploiementBonus inclus dans Molecule
testinfraTests Python expressifsPour assertions complexes (vs verify.yml)
toxTest multi-versions AnsibleAvant publication sur Galaxy
GitHub Actions / GitLab CIAutomatisation pipelinesSur chaque pull request
  • Un rôle = unité réutilisable, testable, distribuable. ~30 % du RHCE EX294.
  • Structure standard : 10 dossiers types avec convention nommage stricte.
  • TDD avec Molecule : écrire le test avant le code — change durablement votre pratique.
  • argument_specs.yml : validation automatique des variables d’entrée — RHCE 2026.
  • Stack tests 2026 : ansible-lint + Molecule + testinfra + tox + CI/CD.
  • Publication : Galaxy public ou Automation Hub privé selon contexte entreprise.

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