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