
Ce guide vous fait écrire votre premier rôle Ansible from scratch avec le rôle fil rouge webserver qui sera enrichi au fil des prochains guides. Vous générez la structure avec ansible-galaxy role init, vous écrivez les tâches dans tasks/main.yml, vous appelez le rôle depuis un playbook, et vous validez avec un test pytest+testinfra.
À la fin, vous aurez un rôle fonctionnel et idempotent qui installe nginx, le démarre, et ouvre le firewall — tout ça en respectant la structure conventionnelle des rôles Ansible.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Générer la structure d’un rôle avec
ansible-galaxy role init. - Écrire
tasks/main.ymlavec 3 tâches FQCN idempotentes (dnf, systemd, firewalld). - Définir des variables par défaut dans
defaults/main.yml. - Documenter le rôle via
meta/main.yml+README.md. - Appeler le rôle depuis un playbook avec
roles:. - Valider l’idempotence en relançant le playbook (résultat :
changed=0).
Prérequis
Section intitulée « Prérequis »- Avoir lu Structure standard d’un rôle.
- Lab fonctionnel avec
web1.labqui répond àansible web1.lab -m ping. - Collection
ansible.posixinstallée (ansible-galaxy collection install ansible.posix).
Étape 1 — Générer la structure
Section intitulée « Étape 1 — Générer la structure »À la racine du projet, créer un dossier roles/ puis générer le rôle :
mkdir -p rolesansible-galaxy role init roles/webserverSortie :
- Role roles/webserver was created successfullyArborescence générée :
Répertoireroles/
Répertoirewebserver/
Répertoiredefaults/
- main.yml
Répertoirefiles/
- …
Répertoirehandlers/
- main.yml
Répertoiremeta/
- main.yml
Répertoiretasks/
- main.yml
Répertoiretemplates/
- …
Répertoiretests/
- …
Répertoirevars/
- main.yml
- README.md
8 dossiers + 2 fichiers racine. Les fichiers main.yml sont créés avec un squelette commenté — à vous de les remplir.
Étape 2 — Écrire les tâches dans tasks/main.yml
Section intitulée « Étape 2 — Écrire les tâches dans tasks/main.yml »Trois tâches simples : installer nginx, démarrer le service, ouvrir le firewall.
---# tasks/main.yml — rôle webserver- name: Installer nginx ansible.builtin.dnf: name: nginx state: present
- name: Démarrer et activer nginx ansible.builtin.systemd_service: name: nginx state: started enabled: true
- name: Ouvrir le service HTTP dans firewalld ansible.posix.firewalld: service: http permanent: true immediate: true state: enabled3 modules, 3 FQCN distincts : ansible.builtin.dnf, ansible.builtin.systemd_service, ansible.posix.firewalld. Chacun est idempotent — re-exécuter le rôle ne change rien si l’état est déjà conforme.
Étape 3 — Définir les variables par défaut
Section intitulée « Étape 3 — Définir les variables par défaut »defaults/main.yml contient les variables que l’utilisateur du rôle peut override. Convention : préfixer par le nom du rôle (webserver_).
---webserver_state: presentwebserver_service_state: startedwebserver_service_enabled: trueÉtape 4 — Documenter le rôle (meta/main.yml)
Section intitulée « Étape 4 — Documenter le rôle (meta/main.yml) »Le fichier meta/main.yml est la carte d’identité du rôle pour Galaxy.
---galaxy_info: author: Stéphane Robert namespace: stephrobert role_name: webserver description: Installer et configurer nginx license: MIT min_ansible_version: "2.16" platforms: - name: EL versions: - "9" - "10" galaxy_tags: - nginx - webserver
dependencies: []Champs essentiels :
role_name+namespace: identifiant Galaxy (stephrobert.webserver).min_ansible_version: version minimum d’Ansible.platforms: OS supportés — Galaxy filtre les recherches selon ces tags.dependencies: autres rôles à pré-installer (vide ici).
Étape 5 — Ajouter des handlers
Section intitulée « Étape 5 — Ajouter des handlers »handlers/main.yml contient les actions réactives déclenchées par notify:.
---- name: Restart nginx ansible.builtin.systemd_service: name: nginx state: restarted
- name: Reload nginx ansible.builtin.systemd_service: name: nginx state: reloadedLes handlers ne s’exécutent pas tout seuls — il faut une tâche qui les notifie via notify: "Restart nginx". C’est le sujet du guide handlers-meta.
Étape 6 — Écrire le playbook qui consomme le rôle
Section intitulée « Étape 6 — Écrire le playbook qui consomme le rôle »À la racine du projet (au-dessus de roles/), créer playbook.yml :
---- name: Déployer le rôle webserver hosts: web1.lab become: true
roles: - role: webserverPas de tasks: dans le playbook — toutes les tâches viennent du rôle. Pattern recommandé : playbooks fins, rôles épais.
Étape 7 — Exécuter le playbook
Section intitulée « Étape 7 — Exécuter le playbook »ansible-playbook playbook.ymlSortie attendue :
PLAY [Déployer le rôle webserver] *********************************
TASK [Gathering Facts] *****************************************ok: [web1.lab]
TASK [webserver : Installer nginx] *****************************changed: [web1.lab]
TASK [webserver : Démarrer et activer nginx] *******************changed: [web1.lab]
TASK [webserver : Ouvrir le service HTTP dans firewalld] *******changed: [web1.lab]
PLAY RECAP *****************************************************web1.lab : ok=4 changed=3 unreachable=0 failed=0Notez le préfixe webserver : sur chaque tâche — Ansible identifie clairement le rôle exécutant. Très utile pour debugger un play multi-rôles.
Étape 8 — Vérifier l’idempotence
Section intitulée « Étape 8 — Vérifier l’idempotence »Re-lancer immédiatement le playbook :
ansible-playbook playbook.ymlSortie attendue : changed=0. Tous les modules sont idempotents — l’état désiré est déjà atteint, rien à faire. C’est la propriété fondamentale d’un bon rôle Ansible : convergence vers un état, pas exécution aveugle.
Étape 9 — Tester nginx
Section intitulée « Étape 9 — Tester nginx »curl http://web1.lab/Vous devriez voir la page d’accueil par défaut de nginx (« Welcome to nginx »).
Pratiquer dans le lab
Section intitulée « Pratiquer dans le lab »Cette page a un lab d’accompagnement complet : labs/roles/creer-premier-role/ dans
stephrobert/ansible-training.
Le lab fournit le rôle webserver pré-écrit + un challenge : créer un second rôle httpd-server pour Apache et le déployer sur db1.lab. Tests automatisés via pytest+testinfra (5 tests).
cd ~/Projets/ansible-training/labs/roles/creer-premier-role/
cat README.md # tuto pas à pasansible-playbook playbook.yml # déployer webserver sur web1cat challenge/README.md # consigne du challengepytest -v challenge/tests/ # valider le challengePièges courants
Section intitulée « Pièges courants »| Symptôme | Cause | Fix |
|---|---|---|
couldn't resolve module/action 'firewalld' | Collection ansible.posix non installée | ansible-galaxy collection install ansible.posix |
Cannot find role 'webserver' | Rôle pas dans roles_path | Vérifier ansible.cfg ou utiliser un path relatif explicite |
firewalld is not running | Service firewalld arrêté sur la cible | sudo systemctl enable --now firewalld puis relancer |
changed=true à chaque run | Une tâche n’est pas idempotente | Vérifier que tous les modules ont un state: ou creates: |
| Curl renvoie « Connection refused » | Port 80 pas ouvert | Vérifier firewall-cmd --list-services sur la cible |
À retenir
Section intitulée « À retenir »ansible-galaxy role init <nom>= générer la structure standard automatiquement.tasks/main.yml= point d’entrée, exécuté quand le rôle est appelé.- FQCN partout :
ansible.builtin.dnf,ansible.posix.firewalld. Mandatory en 2026. - Préfixer les variables avec le nom du rôle (
webserver_state). meta/main.yml= carte d’identité Galaxy.dependencies:= autres rôles requis.- Idempotence : re-jouer le playbook =
changed=0si l’état est déjà conforme. - Pattern recommandé :
playbooks/fins +roles/épais.