
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.