Search code examples
linuxansibleansible-facts

Ansible: How to compare 2 host's services with ansible?


I want to compare 2 Red Hat server's service list by Ansible and print out only the different service that is running.

For instance:

  • server 1 running services: a,b,c,d
  • server 2 running services: c,d,e,f

In this case, I only want to print a,b services.

Below is my playbook.

- hosts: server1:server2
  gather_facts: true
  tasks:
    - name: Run command to get running services on server1
      shell: systemctl list-units --type=service --state=running --no-pager | grep '\.service' | awk '{print $1}'
      register: result_server1
      when: "'server1' in inventory_hostname"

    - name: Run command to get running services on server2
      shell: systemctl list-units --type=service --state=running --no-pager | grep '\.service' | awk '{print $1}'
      register: result_server2
      when: "'server2' in inventory_hostname"

    - name: Set facts for server1 services
      set_fact:
        server1_services: "{{ result_server1.stdout_lines }}"
      when: "'server1' in inventory_hostname"

    - name: Set facts for server2 services
      set_fact:
        server2_services: "{{ result_server2.stdout_lines }}"
      when: "'server2' in inventory_hostname"

    - name: Find the difference between services
      set_fact:
        service_difference: "{{ server1_services | difference(server2_services) }}"
      when: "'server1' in inventory_hostname"

    - name: Print the difference for server2
      debug:
        msg: "Service difference for server1: {{ service_difference }}"
      when: "'server1' in inventory_hostname"

The problem is it prints out all of the services for server1.

TASK [Print differences] **********************************************************************************************************************************************************************
task path: /home/jenkins/workspace/custom-playbooks/2getservicelist.yaml:49
ok: [server1] => {
    "msg": "Service difference for server1: [u'auditd.service', u'crond.service', u'dbus.service', u'[email protected]', u'httpd.service', u'irqbalance.service', u'lvm2-lvmetad.service', u'NetworkManager.service', u'polkit.service', u'postfix.service', u'rhnsd.service', u'rhsmcertd.service', u'rsyslog.service', u'sshd.service', u'systemd-journald.service', u'systemd-logind.service', u'systemd-udevd.service', u'tuned.service', u'vgauthd.service', u'vmtoolsd.service']"

skipping: [server2] => {}
META: ran handlers
META: ran handlers

difference filter can't provide me that I assume. How can I solve this?


Solution

  • A minimal example playbook

    ---
    - hosts: test
      become: true
      gather_facts: false
    
    
      tasks:
    
      - name: Gather Service Facts
        service_facts:
    
      - name: Show all
        debug:
          var: services
    
      - name: Show difference
        ansible.utils.fact_diff:
          before: "{{ hostvars['test1.example.com'].services | to_nice_yaml }}"
          after:  "{{ hostvars['test2.example.com'].services | to_nice_yaml }}"
    

    could result into an output in example of

    changed: [test1.example.com]
    --- before
    +++ after
    @@ -27,11 +27,6 @@
    ...
    -besclient.service:
    -    name: besclient.service
    -    source: systemd
    -    state: running
    ...
    +io.podman.service:
    +    name: io.podman.service
    +    source: systemd
    +    state: inactive
    +    status: disabled
    ...
    +node_exporter.service:
    +    name: node_exporter.service
    +    source: systemd
    +    state: running
    +    status: enabled
    ...
    

    Further Readings

    Use Cases for service_facts and how to use it

    or in general