Aller au contenu
Infrastructure as Code medium

Ansible multi-distro : gérer les paquets sur Debian, RHEL et Arch dans un seul playbook

6 min de lecture

Logo Ansible

Gérer un parc hétérogène (Debian, RHEL, Arch) dans un seul playbook est l’un des cas d’usage les plus courants d’Ansible. Trois stratégies coexistent : le module agnostique package:, le conditionnel when: ansible_os_family == 'X', et les vars par distribution (vars/RedHat.yml, vars/Debian.yml).

Cette page compare les trois approches et donne le pattern idiomatique pour chacune.

  • Choisir entre package:, conditionnels et vars par distribution.
  • Écrire un playbook qui installe des paquets différents selon la distrib.
  • Charger des variables par OS via include_vars:.
  • Détecter la famille via ansible_os_family et ansible_pkg_mgr.
  • Comprendre les facts Ansible (ansible_os_family, ansible_distribution).
  • Avoir lu module package.
- name: Installer git (toutes distribs)
ansible.builtin.package:
name: git
state: present

Avantage : un seul code, fonctionne partout. Limite : le nom du paquet doit être identique sur toutes les distribs. git, curl, vim — OK. apache2 (Debian) vs httpd (RHEL) — KO.

Quand utiliser : paquets dont le nom est universel, playbooks simples.

Stratégie 2 — Conditionnel when: sur ansible_os_family

Section intitulée « Stratégie 2 — Conditionnel when: sur ansible_os_family »
- name: Installer Apache sur RHEL
ansible.builtin.dnf:
name: httpd
state: present
when: ansible_os_family == 'RedHat'
- name: Installer Apache sur Debian
ansible.builtin.apt:
name: apache2
state: present
when: ansible_os_family == 'Debian'

ansible_os_family = famille d’OS, plus stable que ansible_distribution :

FamilleDistributions
RedHatRHEL, AlmaLinux, Rocky, CentOS, Fedora
DebianDebian, Ubuntu, Linux Mint
ArchlinuxArch, Manjaro
SuseopenSUSE, SLES

Avantage : précision maximale, accès aux options spécifiques (enablerepo:, update_cache:). Limite : verbeux dès qu’il y a plus de 2-3 paquets.

Stratégie 3 — Vars par distribution (recommandé pour > 5 paquets)

Section intitulée « Stratégie 3 — Vars par distribution (recommandé pour > 5 paquets) »

Structure de rôle :

roles/web/
├── tasks/main.yml
└── vars/
├── RedHat.yml
└── Debian.yml

vars/RedHat.yml :

apache_pkg: httpd
apache_service: httpd
apache_user: apache

vars/Debian.yml :

apache_pkg: apache2
apache_service: apache2
apache_user: www-data

tasks/main.yml :

- name: Charger les vars de la distrib
ansible.builtin.include_vars: "{{ ansible_os_family }}.yml"
- name: Installer Apache
ansible.builtin.package:
name: "{{ apache_pkg }}"
state: present
- name: Activer Apache
ansible.builtin.systemd_service:
name: "{{ apache_service }}"
enabled: true
state: started

Avantage : tâches propres et lisibles, séparation données/logique, scalable à des dizaines de paquets. Pattern standard dans les rôles Ansible Galaxy de qualité.

- name: Repos EPEL uniquement sur RHEL 9+
ansible.builtin.dnf:
name: epel-release
state: present
when:
- ansible_os_family == 'RedHat'
- ansible_distribution_major_version | int >= 9

ansible_distribution_major_version est une string — toujours convertir avec | int avant comparaison numérique.

Détecter le gestionnaire de paquets via ansible_pkg_mgr

Section intitulée « Détecter le gestionnaire de paquets via ansible_pkg_mgr »
- name: Afficher le gestionnaire detecte
ansible.builtin.debug:
msg: "Gestionnaire : {{ ansible_pkg_mgr }}"

ansible_pkg_mgr retourne : apt, dnf, dnf5, yum, pacman, zypper. Utile pour des assertions ou des rapports, mais le module package: l’utilise déjà sous le capot.

SymptômeCauseFix
Could not find a match for 'apache2' sur RHELNom de paquet Debian-onlyUtiliser vars/Debian.yml + vars/RedHat.yml
when: ansible_distribution == 'Ubuntu' rate sur Debianansible_distribution trop spécifiquePréférer ansible_os_family == 'Debian'
Erreur sur Fedora alors que play RHEL fonctionneansible_os_family = RedHat, mais dnf5 au lieu de dnfUtiliser package: ou tester ansible_pkg_mgr
include_vars ne charge rienFichier absent pour la distrib testéefailed_when: ou condition with_first_found:
  • package: suffit quand le nom est universel (git, curl, vim).
  • when: ansible_os_family pour des cas isolés ou des options spécifiques.
  • include_vars: "{{ ansible_os_family }}.yml" = pattern standard pour rôles multi-distro.
  • ansible_distribution_major_version est une string — | int avant comparaison.
  • ansible_pkg_mgr détecte le gestionnaire : apt, dnf, pacman, zypper.

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