Aller au contenu
English
English
Infrastructure as Code medium

Consommer un rôle Ansible : roles, import_role, include_role, tasks_from

80 min de lecture

Logo Ansible

Ansible offre 3 façons de consommer un rôle dans un playbook : roles: classique (statique, exécuté avant tasks:), import_role (statique, parsé au démarrage du playbook), include_role (dynamique, parsé au runtime, seul à accepter loop:). Cette page explique quand utiliser chacun et démontre tasks_from: pour cibler un fichier spécifique du rôle.

  • Le pattern roles: classique au top du play.
  • import_role : statique, parsé au démarrage.
  • include_role : dynamique, seul à accepter loop:.
  • tasks_from: pour cibler un fichier autre que main.yml.
  • Quand préférer chacun selon le contexte.

Ce tableau se lit par la contrainte, pas par la forme : c'est le besoin de la colonne de gauche qui désigne le mécanisme, jamais l'inverse. Deux lignes suffisent à trancher la plupart des cas, celle de la boucle, qui impose include_role, et celle du placement au milieu des tâches, qui écarte la section roles:.

BesoinPattern recommandé
Rôle exécuté toujours au début du playroles: classique
Rôle exécuté au milieu des tasks (avant/après autres tasks)import_role
Rôle exécuté conditionnellement (when:)les trois l'acceptent ; include_role saute le rôle en un bloc
Rôle exécuté en boucle sur une listeinclude_role + loop:
Cibler tasks/configure.yml au lieu de tasks/main.ymlimport_role ou include_role + tasks_from:

C'est la forme la plus ancienne et la plus lisible : une liste de rôles posée au niveau du play, jouée avant ses tasks:. Elle convient dès que l'ordre voulu est simplement « ces rôles d'abord », et c'est encore la majorité des cas. Ses 2 limites apparaissent quand un rôle doit s'intercaler entre deux tâches, ou tourner en boucle.

- name: Pattern roles classique
hosts: web1.lab
become: true
roles:
- role: webserver # ← équivalent à `import_role` au début du play

Comportement :

  • Le rôle est exécuté AVANT les tasks: du play.
  • Statique : parsé au démarrage du playbook.
  • Un when: posé à côté de role: est accepté, et recopié sur chaque tâche du rôle.
- name: Pattern import_role
hosts: web1.lab
become: true
tasks:
- name: Message avant le rôle
ansible.builtin.debug:
msg: "Avant l'import du rôle webserver"
- name: Importer le rôle webserver
ansible.builtin.import_role:
name: webserver
- name: Message après le rôle
ansible.builtin.debug:
msg: "Après l'import du rôle webserver"

Comportement :

  • Le rôle s'exécute à l'endroit où import_role: est appelé (au milieu des tasks).
  • Statique : parsé au démarrage du playbook (les tâches du rôle sont visibles dans --list-tasks).
  • when: fonctionne, mais il est recopié sur chaque tâche du rôle : la sortie affiche une ligne skipping: par tâche, et la condition est réévaluée à chacune.
  • loop: est refusé : Ansible rejette le playbook au chargement, sur You cannot use loops on 'import_role' statements.

Cas d'usage : intégrer un rôle dans un séquencement précis (pre_tasks → import_role → post_tasks).

L'inclusion est la seule des trois formes résolue à l'exécution, au moment où la tâche est atteinte. Cela lui donne une capacité qu'aucune autre n'a, la boucle, et lui coûte une chose : ses tâches n'apparaissent pas dans --list-tasks, puisqu'elles ne sont pas connues au chargement.

- name: Pattern include_role
hosts: db1.lab
become: true
tasks:
- name: Inclure le rôle UNIQUEMENT sur RHEL 9+
ansible.builtin.include_role:
name: webserver
tasks_from: main.yml # ← peut cibler un autre fichier
vars:
webserver_listen_port: 9090
when: ansible_distribution_major_version | int >= 9

Comportement :

  • Le rôle est inclus dynamiquement au runtime, au moment où la tâche est atteinte.
  • Supporte loop:, ce qu'aucune des deux autres formes ne permet.
  • Sur un when: faux, saute le rôle en un seul bloc, sans une ligne par tâche.
  • Pas visible dans --list-tasks (parsing au runtime).
  • Plus lent que import_role car parsing à chaque exécution.

Cas d'usage :

  • Conditionnel sur un fact (ansible_os_family).
  • Boucle sur une liste de configs.
  • Logique de branchement complexe.

Un rôle peut avoir plusieurs fichiers de tâches :

roles/webserver/tasks/
├── main.yml ← entrypoint par défaut
├── install.yml
├── configure.yml
└── secure.yml

Pour cibler configure.yml uniquement (sans rejouer install) :

- name: Reconfigurer nginx (sans réinstaller)
ansible.builtin.import_role:
name: webserver
tasks_from: configure.yml

Avantage : un rôle peut exposer plusieurs entrypoints logiques. L'utilisateur du rôle choisit quoi exécuter selon son besoin.

Quelle que soit la forme d'appel, le paramétrage passe par une clé vars: posée au niveau du rôle, avec la même syntaxe. Les trois extraits ci-dessous montrent volontairement le même réglage, webserver_listen_port: 8080, écrit pour roles:, pour import_role puis pour include_role : c'est l'appel qui change, jamais le passage de variables.

roles:
- role: webserver
vars:
webserver_listen_port: 8080
webserver_worker_processes: 4
- name: Appeler le rôle webserver à l'analyse du playbook
ansible.builtin.import_role:
name: webserver
vars:
webserver_listen_port: 8080
- name: Appeler le rôle webserver au moment de l'exécution
ansible.builtin.include_role:
name: webserver
vars:
webserver_listen_port: 8080

Les vars: au niveau du rôle ont une priorité élevée (équivalent à --extra-vars). Surchargent defaults/main.yml et vars/main.yml des autres niveaux.

public: true, exposer les variables du rôle au play

Section intitulée « public: true, exposer les variables du rôle au play »
- name: Inclure le rôle en exposant ses variables au play
ansible.builtin.include_role:
name: webserver
public: true # ← variables exposées au play parent

Par défaut, public vaut false : les vars/ et les defaults/ du rôle restent cantonnés au rôle. Avec public: true, ils deviennent visibles dans le play appelant, y compris pour les tâches qui suivent l'inclusion. L'option existe depuis ansible-core 2.7 et n'a pas d'équivalent sur import_role, dont les variables sont toujours exposées. À employer avec parcimonie : elle mélange l'espace de noms du rôle et celui du play.

Les trois façons d'appeler un rôle se ressemblent sur le papier, leur différence n'apparaît qu'à l'exécution. Le lab vous fait invoquer le même rôle par roles:, par import_role puis par include_role dans un seul playbook à trois plays, et constater lequel honore réellement un when: évalué au runtime. La validation relit la structure du playbook et exige que les trois formes soient présentes, condition comprise.

Ces cinq symptômes ont une cause commune : la différence entre chargement et exécution n'a pas été prise en compte. Les deux premiers viennent d'un import_role là où une inclusion s'imposait, le troisième d'un chemin de fichier, et les deux derniers du coût propre à chaque forme, visibilité d'un côté, temps de démarrage de l'autre.

SymptômeCauseFix
Une ligne skipping: par tâche du rôleLe when: d'un import_role est recopié sur chaque tâcheComportement normal ; include_role saute le rôle en un bloc
You cannot use loops on 'import_role' statementsloop: est interdit sur un importPasser à include_role
Variable du rôle pas visible après son exécutionScope par défaut privéUtiliser public: true (avec parcimonie)
tasks_from: configure.yml planteFichier inexistant ou mal nomméVérifier roles/<role>/tasks/configure.yml
--list-tasks ne montre pas les tâches du rôleinclude_role (dynamique)Utiliser import_role pour visualisation
Lent au démarrage du playbookBeaucoup de import_role (parsing initial)Bascule vers include_role pour les rôles conditionnels

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • roles: = exécution avant tasks:. Statique. Le plus simple.
  • import_role = exécution au milieu des tasks. Statique (parsing initial).
  • include_role = exécution au milieu des tasks. Dynamique (parsing runtime). Seul à accepter loop:.
  • tasks_from: cible un fichier de tâches autre que main.yml.
  • vars: sur le rôle = priorité haute, override les defaults/vars du rôle.
  • Installer rôles Galaxy : récupérer le rôle que vous consommez, dans une version figée.
  • RHEL System Roles : un cas complet de consommation d'un rôle tiers, du requirements.yml à la vérification côté service.
  • Vault dans les rôles : passer un secret à un rôle sans l'écrire en clair dans le playbook appelant.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn