Service_facts doesn't gather facts on systemd timers

I want to disable a systemd timer
So i see there is an example on enabling a timer:

- name: enable a timer for dnf-automatic
  systemd:
    name: dnf-automatic.timer
    state: started
    enabled: yes

But i would like to collect facts about the services/timers and then disable services/timers based on the availability.

- name: get info
  ansible.builtin.service_facts:

- name: disable services/timers
  ansible.builtin.systemd:
    name: "{{ item }}"
    state: stopped
    enabled: no
  loop:
    - motd-news.service
    - motd-news.timer
  when: "item in ansible_facts.services"

fyi, the timer wont be disabled because its not included in the facts

Well, to be fair, timers are not services and so they don’t really belong in service_facts.

There are a number of other types of systemd units which also do not appear there but which can be managed using Ansible: I’m managing path and mount units too.

2 Likes

I understand it doesn’t belong in service_facts. But can i find it at all in other facts then? ofc I can use the command: option but im curious if its possbile to do it within ansible.

There’s a few ways you could do this:

  1. Register the output from a shell command
  2. Use a custom facts file for the setup module to gather
  3. You can make your own custom facts module.

The first option is the easiest, and leads into 2 as a possible alternative. Simply run systemctl list-unit-files --all --output=json using the command module and register the output. Then you can loop through this however you please. This gets you all of the unit files, their current and default state (preset), but it does not get you their current status (active/running/exited/failed, etc).

- name: get info
  ansible.builtin.command: systemctl list-unit-files --all --output=json
  register: systemd_units

- name: set fact
  set_fact:
    systemd_facts: "{{ systemd_units.stdout | from_json | map(attribute='unit_file') }}"

- name: disable services/timers
  ansible.builtin.systemd:
    name: "{{ item }}"
    state: stopped
    enabled: no
  loop:
    - motd-news.service
    - motd-news.timer
  when: item in systemd_facts

If you want gather_facts to do this instead, make a shell script using the same command and save it as /etc/ansible/facts.d/systemd.fact (make sure it’s executable and has the shebang). You’ll have to change the when: condition to use the ansible_local.systemd fact.

Or lastly, you could go implement an actual systemd_facts module, since there is an RFE for it, but no work has been done.

If you need the run status of the systemd units, take a look at some of the other systemctl commands. If you just want timers, you can add a pattern filter to the command: systemctl list-unit-files *.timer --all --output=json If you only want active/loaded units, you can switch to systemctl list-units *.timer --all --output=json, and change the mapped attribute to map(attribute='unit').

2 Likes