Aller au contenu
Infrastructure as Code medium

Dépendances entre rôles Ansible : meta/main.yml dependencies

9 min de lecture

Logo Ansible

Un rôle peut dépendre d’autres rôles via meta/main.yml. Avant que tasks/main.yml du rôle s’exécute, les dépendances tournent en cascade. Pattern utile pour : firewall_setup avant webserver, selinux_setup avant httpd. Cette page démontre le pattern, l’ordre exact de chargement, et les anti-patterns à éviter.

  • Déclarer des dépendances dans meta/main.yml.
  • L’ordre exact de chargement (dependencies → tasks → handlers).
  • Passer des variables aux dépendances.
  • allow_duplicates pour ré-exécuter un rôle avec des params différents.
  • Anti-patterns : profondeur excessive, dépendances circulaires.
roles/webserver/meta/main.yml
---
galaxy_info:
...
dependencies:
- role: selinux_setup
vars:
selinux_state: enforcing
- role: firewall_setup
vars:
firewall_zones:
- public

Ordre d’exécution :

  1. selinux_setup (1ère dépendance)
  2. firewall_setup (2ème dépendance)
  3. Puis webserver/tasks/main.yml

Les dépendances tournent avant le rôle qui les déclare.

playbook.yml appelle webserver
├── webserver/meta/main.yml dependencies:
│ ├── selinux_setup
│ │ └── selinux_setup/tasks/main.yml
│ └── firewall_setup
│ └── firewall_setup/tasks/main.yml
└── webserver/tasks/main.yml

Si selinux_setup lui-même déclare des dépendances, elles tournent avant lui — récursion en profondeur.

dependencies:
- role: firewall_setup
vars:
firewall_zones:
- public
- dmz
firewall_open_services:
- http
- https

Les variables passées au niveau de la dépendance ont priorité élevée — équivalent au vars: sur un roles: classique. Surchargent les defaults/ du rôle dépendant.

Pas possible directement dans dependencies: — pas de when: au niveau meta.

Workaround : conditionner dans le rôle dépendant lui-même :

roles/firewall_setup/tasks/main.yml
- name: Configurer firewalld
ansible.builtin.systemd_service:
name: firewalld
state: started
when: firewall_enabled | default(true)

Ou utiliser include_role avec when: au lieu de dependencies si c’est conditionnel.

allow_duplicates: true — ré-exécuter avec params différents

Section intitulée « allow_duplicates: true — ré-exécuter avec params différents »

Par défaut, un rôle n’est exécuté qu’UNE FOIS dans un play, même s’il est listé plusieurs fois (déduplication automatique). Pour forcer la ré-exécution :

roles/database/meta/main.yml
allow_duplicates: true

Permet :

roles:
- role: database
vars: { db_name: prod, db_port: 5432 }
- role: database
vars: { db_name: staging, db_port: 5433 } # ← exécuté car allow_duplicates: true

Sans allow_duplicates: true, le second appel serait ignoré.

webapp → webserver → tls_config → ca_setup → root_ca_distrib

5 niveaux de profondeur. Debug = horreur. Préférer :

# playbook.yml — orchestrateur
- hosts: all
roles:
- root_ca_distrib
- ca_setup
- tls_config
- webserver
- webapp

À plat. Plus lisible.

A dependencies: [B]
B dependencies: [C]
C dependencies: [A]

Ansible refuse — erreur recursive role dependency. À détecter via ansible-galaxy install -r requirements.yml qui valide le graphe.

Mettre toutes les briques de la stack en dependencies du rôle principal :

roles/webapp/meta/main.yml
dependencies:
- role: nginx
- role: php-fpm
- role: postgresql
- role: redis
- role: certbot

Mauvais : le rôle webapp devient inutilisable seul (toutes les deps sont obligatoires). Préférer un playbook qui orchestre.

Le pattern import_role: ou include_role: au lieu de dependencies:

Section intitulée « Le pattern import_role: ou include_role: au lieu de dependencies: »

Souvent plus propre d’appeler les rôles depuis le playbook plutôt que via dependencies: :

playbook.yml
- hosts: webservers
tasks:
- name: Setup SELinux
ansible.builtin.import_role:
name: selinux_setup
- name: Setup firewall
ansible.builtin.import_role:
name: firewall_setup
- name: Deploy webserver
ansible.builtin.import_role:
name: webserver

Avantages :

  • Visibilité : le playbook montre l’ordre clairement.
  • Conditionnel possible avec include_role + when:.
  • Modulaire : webserver peut être utilisé seul (sans déclencher selinux).

dependencies: reste valable pour des dépendances structurelles (ex : un rôle nginx-tls dépend nécessairement de nginx-base).

Cette page a un lab d’accompagnement : labs/roles/dependencies/ dans stephrobert/ansible-training.

Le lab pose un rôle webserver avec 2 dépendances (selinux_setup + firewall_setup). Les rôles dépendants sont créés. 5 tests structure validés.

Fenêtre de terminal
cd ~/Projets/ansible-training/labs/roles/dependencies/
cat roles/webserver/meta/main.yml # déclare les deps
ls roles/ # webserver + selinux_setup + firewall_setup
pytest -v challenge/tests/ # 5 tests
SymptômeCauseFix
recursive role dependencyCycle dans le grapheRefactorer pour casser le cycle
Dépendance ignorée silencieusementDéjà jouée dans le même play (déduplication)allow_duplicates: true si volontaire
Variables des deps en collisionPréfixage absentPréfixer <role>_* dans chaque rôle
Profondeur > 2 niveauxArchitecture mal penséeBouger vers playbook orchestrateur
when: sur dep ignoréPas supporté au niveau metaConditionner dans le rôle dépendant
  • meta/main.yml dependencies: chaîne les rôles avant tasks/main.yml.
  • Ordre : dependencies (récursif) → tasks → handlers.
  • vars: sur dep = priorité haute, surcharge defaults.
  • allow_duplicates: true force la ré-exécution avec params différents.
  • Max 2 niveaux de profondeur — sinon préférer un playbook orchestrateur.
  • import_role/include_role dans le playbook = alternative plus visible.

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