
ansible.builtin.service_facts: collecte l'état de tous les services systemd d'un managed node, running/stopped, enabled/disabled, masked. C'est l'outil pour conditionner une tâche ou auditer un parc sans parser à la main systemctl list-units.
Le résultat atterrit dans ansible_facts.services sous forme de dict, directement utilisable dans when: ou un template Jinja.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Collecter l'état de tous les services en une tâche.
- Conditionner un
started:ouenabled:selon l'état actuel. - Auditer un parc (services attendus, services en trop).
- Éviter les redémarrages inutiles sur des plays massifs.
Prérequis
Section intitulée « Prérequis »- Pas besoin de
become:(lecture seule). - Fonctionne sur systemd, upstart, sysv, AIX SRC, OpenWrt.
Collecter et afficher l'état d'un service
Section intitulée « Collecter et afficher l'état d'un service »- name: Collecter les services ansible.builtin.service_facts:
- name: Etat de nginx ansible.builtin.debug: msg: "{{ ansible_facts.services['nginx.service'].state }}"Structure du dict retourné :
ansible_facts: services: nginx.service: state: running status: enabled source: systemdstate = running, stopped, unknown. status = enabled, disabled, static, masked.
Démarrer un service uniquement s'il est arrêté
Section intitulée « Démarrer un service uniquement s'il est arrêté »- name: Collecter les services ansible.builtin.service_facts:
- name: Demarrer nginx si arrete ansible.builtin.systemd_service: name: nginx.service state: started when: ansible_facts.services['nginx.service'].state != 'running'Avantage idempotent : sans service_facts, systemd_service: state: started reste idempotent au niveau API, mais Ansible affiche ok même quand le service n'est pas vraiment vérifié. Ici, vous lisez d'abord l'état et n'agissez que si nécessaire, utile pour des rapports ou des handlers conditionnels.
Activer un service au démarrage si besoin
Section intitulée « Activer un service au démarrage si besoin »- name: Collecter les services ansible.builtin.service_facts:
- name: Activer chronyd au boot ansible.builtin.systemd_service: name: chronyd.service enabled: true when: ansible_facts.services['chronyd.service'].status != 'enabled'status: distingue enabled (démarrage auto), disabled, static (pas d'unit [Install], démarré seulement si dépendance), masked (interdit de démarrer).
Auditer la présence d'un service
Section intitulée « Auditer la présence d'un service »Pattern fréquent : vérifier que tous les services attendus sont installés sur un parc.
- name: Collecter les services ansible.builtin.service_facts:
- name: Verifier que firewalld est installe ansible.builtin.assert: that: - "'firewalld.service' in ansible_facts.services" fail_msg: "firewalld absent — installer le paquet"'firewalld.service' in ansible_facts.services teste juste la présence du dict, pas l'état. Service installé même si désactivé → la clé existe.
Détecter les services masked (potentiellement dangereux)
Section intitulée « Détecter les services masked (potentiellement dangereux) »- name: Collecter les services ansible.builtin.service_facts:
- name: Lister les services masked ansible.builtin.debug: msg: "{{ item.key }}" loop: "{{ ansible_facts.services | dict2items }}" when: item.value.status == 'masked'Un service masked ne peut pas être démarré, utile pour valider qu'un service n'a pas été désactivé en urgence par un opérateur et oublié.
Pièges courants
Section intitulée « Pièges courants »| Symptôme | Cause | Fix |
|---|---|---|
KeyError: 'nginx.service' | Service pas installé, accès direct | Tester d'abord 'nginx.service' in ansible_facts.services |
Service présent mais state: unknown | Service non systemd, ou lecture incomplète | Vérifier via systemctl status à la main |
| Lent sur grandes machines (> 200 services) | Pas de cache | Lancer une fois en début de play, réutiliser ensuite |
status absent dans certains résultats | Backend non systemd (sysv) | Tester .state plutôt que .status |
À retenir
Section intitulée « À retenir »service_facts:= lecture pure, pas d'écriture, pas destate:.- Résultat dans
ansible_facts.services, dict indexé par nom complet (nginx.service). state: running/stopped,status: enabled/disabled/static/masked.- Combiner avec
assertpour auditer la conformité d'un parc. - Lancer une seule fois en début de play, les facts persistent.