ansiblesystemdsystemctl

Ansible: How to get disabled but running services?


I would like to walk over lots of hosts and get all services that were manually started (systemctl start xxxx) without being enabled first (systemctl enable xxxx) and also vice-versa all services which are disabled (systemctl disable xxxx) but still running (because have not been stopped).

And instead of automatically 'fixing' all of the above found problems I just would like to have them output to my shell.

Something like a for each loop over systemctl list-unit-files --state=disabled and running every row through systemctl is-active would probably work, but I would need to transfer a small SH script to every host...

Can this be done by Ansible alone? (using RHEL7 Update 7 with kernel 3.10.x)

Edit: This is my playbook so far, but I can not get the loop working:

---
- hosts: all
  gather_facts: no
  tasks:
     - name: get service facts
       service_facts:
     - name: show report
       when:
        - ansible_facts.services[item + '.service'].state == 'running'
        - ansible_facts.services[item + '.service'].status == 'disabled'
       debug:
         msg: "{{ ansible_facts.services[item + '.service'].status == 'disabled' }}"
       loop:
         ansible_facts.services

Solution

  • Regarding your question

    Can this be done by Ansible alone?

    the short answer is: yes, of course. This is what Ansible is made for.

    In respect to your headline

    How to get disabled but running services?

    and the comment

    Have you tried ansible.builtin.service_facts

    I've prepared a short test which will show the structure of ansible_facts.services.

    ---
    - hosts: localhost
      become: no
      gather_facts: no
    
      tasks:
    
      - name: Gather Service Facts
        service_facts:
    
      - name: Show Service Facts
        debug:
          msg: "{{ ansible_facts.services }}"
    

    Which is than, in example for one of the services

    auditd.service:
      name: auditd.service
      source: systemd
      state: running
      status: enabled
    

    So you will need to loop over the result set and looking for ansible_facts.services[YOURSERVICE].state and ansible_facts.services[YOURSERVICE].status.

    In respect to your description

    ... services which are disabled (systemctl disable xxxx) but still running (because have not been stopped) ...

    you may have a look into the answer to how to declare a variable for service_facts.

    In respect of your comment

    ... how I can do the when condition for all services ...

    and the already mentioned loop over the result, I've added for the test setup

    - name: Loop over all services and print name
      debug:
        msg: "{{ item }}"
      when:
        - ansible_facts.services[item].state == 'running'
        - ansible_facts.services[item].status != 'enabled'
      with_items: "{{ ansible_facts.services }}"
    

    and found it working.

    You may need to adjust the conditionals since that query will report services in status static like dbus or systemd-journald too. Please take also note that a service can also have an unknow status. In example

    splunk.service:
      name: splunk.service
      source: systemd
      state: running
      status: unknown
    

    or

    systemctl status splunk
    ā— splunk.service - SYSV: Splunk indexer service
       Loaded: loaded (/etc/rc.d/init.d/splunk; bad; vendor preset: disabled)
       Active: active (running) ...