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 tracking. 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