
Un rôle Ansible est l’équivalent d’un module Terraform ou d’un chart Helm : une brique réutilisable qui packagde tâches, variables, templates, handlers et tests autour d’un objectif unique. Vous écrivez un rôle nginx une fois, vous le réutilisez dans 5 projets, vous le maintenez à un seul endroit.
Cette page explique pourquoi un rôle est supérieur à un long playbook, quand basculer du playbook au rôle, et ce que vous gagnez réellement (avec un exemple concret de refactoring).
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Le problème que les rôles résolvent : duplication, drift, code monolithique.
- La comparaison avec les modules Terraform et les charts Helm.
- Le ROI réel d’un refactoring playbook → rôle (avant/après).
- Quand basculer : critères pratiques pour décider.
- Anti-patterns : ce qu’il ne faut PAS mettre dans un rôle.
Le problème — un long playbook qui grossit
Section intitulée « Le problème — un long playbook qui grossit »Vous démarrez un projet pour automatiser un déploiement web. Première version : 50 lignes pour installer nginx. Trois mois plus tard, votre playbook.yml ressemble à ça :
---- name: Déployer toute l'infra web hosts: webservers become: true vars: nginx_version: "1.26.1" nginx_workers: 4 nginx_port: 80 php_version: "8.3" php_modules: - mysql - mbstring - curl db_host: db1.lab db_port: 5432 # ... 30 autres variables ...
tasks: # 50 tâches nginx - name: Installer nginx ansible.builtin.dnf: name: nginx state: present - name: Configurer nginx.conf ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf # ... 48 autres tâches nginx ...
# 30 tâches php-fpm - name: Installer PHP ...
# 40 tâches application métier ...
handlers: # 10 handlers ...500 lignes, 120 tâches, 30 variables, 10 handlers, 7 templates. Ce playbook fonctionne sur votre serveur de dev. Mais il pose 5 problèmes structurels.
Problème 1 — Pas réutilisable
Section intitulée « Problème 1 — Pas réutilisable »Demain, nouveau projet qui a aussi besoin de nginx. Vous copiez-collez les 50 tâches nginx dans le nouveau playbook. Drift garanti : à la première mise à jour de la config nginx, les deux versions divergent silencieusement.
Problème 2 — Pas testable isolément
Section intitulée « Problème 2 — Pas testable isolément »Vous voulez tester que nginx démarre correctement, indépendamment de PHP et de la base. Impossible avec ce playbook : pour tester nginx, vous devez rejouer toute la stack, attendre 5 minutes, et chercher dans le log si nginx a marché.
Problème 3 — Mélange des responsabilités
Section intitulée « Problème 3 — Mélange des responsabilités »Une modification urgente sur PHP nécessite de comprendre tout le contexte (nginx, base, app). Risque d’erreur élevé. Le diff Git est illisible : un changement sur la version PHP touche un fichier de 500 lignes que personne ne lit en entier.
Problème 4 — Variables disséminées
Section intitulée « Problème 4 — Variables disséminées »Les 30 variables sont au top du playbook. Trois mois plus tard, vous ne savez plus laquelle est vraie (par défaut), laquelle est forcée, laquelle vient d’un group_vars/. Le vars: du play écrase silencieusement vos group_vars/all.yml.
Problème 5 — Pas distribuable
Section intitulée « Problème 5 — Pas distribuable »Votre collègue veut nginx dans son projet. Comment lui donner ? Copier-coller 50 tâches ? Lui pousser un repo ? Aucun de ces deux flux n’est satisfaisant pour un partage à grande échelle.
La solution — un rôle par responsabilité
Section intitulée « La solution — un rôle par responsabilité »Refactorer en 3 rôles :
roles/├── nginx/ ← 50 tâches + 5 templates + 10 variables├── php-fpm/ ← 30 tâches + 3 templates + 8 variables└── app/ ← 40 tâches + 4 templates + 12 variablesLe playbook devient :
---- name: Déployer toute l'infra web hosts: webservers become: true
roles: - role: nginx vars: nginx_version: "1.26.1" nginx_workers: 4 - role: php-fpm vars: php_version: "8.3" - role: app vars: db_host: db1.lab20 lignes au lieu de 500. Lisible. Modulaire. Chaque rôle est :
- Réutilisable :
roles: - nginxdans un autre projet. - Testable isolément : Molecule sur le rôle nginx sans toucher PHP ni l’app.
- Versionnable indépendamment :
nginx@1.2.0,php-fpm@2.0.1dansrequirements.yml. - Documentable par un README clair (paramètres, exemples).
- Distribuable sur Galaxy ou un Automation Hub privé.
Comparaison avec d’autres outils IaC
Section intitulée « Comparaison avec d’autres outils IaC »Les rôles Ansible occupent dans l’écosystème la même niche que :
| Outil | Unité de réutilisation | Source |
|---|---|---|
| Ansible | Rôle | Galaxy, Automation Hub, GitHub |
| Terraform | Module | Terraform Registry, Git |
| Kubernetes | Helm chart | Artifact Hub, OCI registry |
| Pulumi | Component | Pulumi Registry, NPM/PyPI |
| Salt | Formula | Salt Formulas (GitHub) |
| Chef | Cookbook | Chef Supermarket |
| Puppet | Module | Puppet Forge |
Le concept est identique partout : un dossier structuré avec des conventions, une API d’entrée (variables/inputs), et un comportement encapsulé. Si vous avez utilisé un module Terraform, vous comprenez déjà 80 % d’un rôle Ansible — la syntaxe diffère mais la philosophie est identique.
ROI réel du refactoring — chiffres
Section intitulée « ROI réel du refactoring — chiffres »Voici le résultat concret d’un refactoring de production sur 5 projets utilisant nginx :
| Métrique | Avant (playbooks) | Après (rôle nginx + 5 projets) |
|---|---|---|
| Lignes de code totales (nginx) | 5 × 50 = 250 | 1 × 50 + 5 × 5 = 75 |
| Temps de mise à jour de la config nginx | 5 fichiers à éditer | 1 fichier à éditer |
| Risque de drift | Élevé | Nul (source unique) |
| Testabilité | 0 | Molecule isolé |
| Onboarding nouveau dev | Lit 500 lignes | Lit README.md du rôle |
Gain factuel : 60 % de code en moins, 100 % de drift en moins, testabilité de 0 à 100 %.
Quand basculer du playbook au rôle ?
Section intitulée « Quand basculer du playbook au rôle ? »Critères de décision simples :
- Le code va être réutilisé ailleurs (autre projet, autre environnement). → Rôle dès le départ.
- Le playbook dépasse 100 lignes et grossit. → Refactor en plusieurs rôles.
- Plusieurs équipes doivent collaborer. → Rôles (ownership clair).
- Vous voulez tester avec Molecule. → Rôle (Molecule fonctionne sur les rôles, pas les playbooks).
- Le code touche un service identifiable (nginx, postgres, vault). → Rôle par service.
À l’inverse, ne créez pas de rôle pour :
- Un playbook one-shot de migration unique (purge + import).
- Une glue très spécifique à un projet (reportez dans
tasks/du playbook). - Du code expérimental que vous n’êtes pas sûr de garder.
Anti-patterns à éviter
Section intitulée « Anti-patterns à éviter »Anti-pattern 1 — Le rôle « base »/« common »
Section intitulée « Anti-pattern 1 — Le rôle « base »/« common » »Tentation : un rôle common qui contient « tout ce que toutes les machines doivent avoir » (sshd, ntp, monitoring, users…). Problème : devient un fourre-tout ingérable. Préférer un rôle par responsabilité : sshd, ntp, monitoring, users. Plus long à écrire, infiniment plus maintenable.
Anti-pattern 2 — Les rôles imbriqués profondément
Section intitulée « Anti-pattern 2 — Les rôles imbriqués profondément »Un rôle webapp qui dépend du rôle nginx qui dépend du rôle tls qui dépend du rôle dns… 4 niveaux de profondeur. Debug = horreur. Préférer 2 niveaux maximum ou utiliser un playbook orchestrateur qui appelle les rôles à plat.
Anti-pattern 3 — Variables hardcodées dans les tasks
Section intitulée « Anti-pattern 3 — Variables hardcodées dans les tasks »# ❌ Mauvais- name: Configurer nginx ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf vars: nginx_version: "1.26.1" # ← hardcodé dans la taskLe rôle n’est plus paramétrable. Préférer defaults/main.yml :
# ✅ Bonnginx_version: "1.26.1"
# tasks/main.yml- name: Configurer nginx ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.confAnti-pattern 4 — Tâches non idempotentes
Section intitulée « Anti-pattern 4 — Tâches non idempotentes »# ❌ Mauvais- name: Vider le cache ansible.builtin.command: rm -rf /var/cache/nginx/*À chaque exécution, changed=true. Préférer un module dédié avec idempotence :
# ✅ Bon- name: Vider le cache ansible.builtin.file: path: /var/cache/nginx state: absent- name: Recréer le cache ansible.builtin.file: path: /var/cache/nginx state: directory mode: "0755"Anti-pattern 5 — Pas de README ni d’argument_specs.yml
Section intitulée « Anti-pattern 5 — Pas de README ni d’argument_specs.yml »Un rôle sans documentation est inutilisable par autrui — voire par vous-même 6 mois plus tard. Mandatory : README.md + meta/argument_specs.yml (validation des variables).
À retenir
Section intitulée « À retenir »- Un rôle = brique réutilisable testable distribuable. Équivalent d’un module Terraform.
- Refactor playbook → rôle dès que le code dépasse 100 lignes ou doit être réutilisé.
- ROI mesurable : 60 % de code en moins, 100 % de drift en moins, testabilité native.
- Un rôle = une responsabilité. Pas de rôle « base »/« common » fourre-tout.
- Anti-patterns : variables hardcodées, tâches non-idempotentes, pas de README.
- Imbrication max 2 niveaux — préférer un playbook orchestrateur.