
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.