Ansible: How To Compare 1 Host's Services with Multiple Host's Services?

43 Views Asked by At

I had an issue with comparing services for 2 server's with ansible. That is solved by the below yaml. My question is, how can I compare 1 host's service list with multiple host?

---
- 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 }}"

I changed the after section for looping through all of my hosts and compare those server's services with my first host which is in before section. My hosts are in my inventory file grouped with selected_hosts tag.

ansible.utils.fact_diff:
      before: "{{ hostvars['test1.example.com'].services | to_nice_yaml }}"
      after: "{% for ip_address in groups['selected_hosts'] %}
                {{ hostvars[ip_address].services | to_nice_yaml }}
              {% endfor %}"

The problem here is, despite my yaml is correctly looping all of my servers from the inventory file, it won't show any differences for services. Example output is below:

+ NetworkManager-dispatcher.service:
+    name: NetworkManager-dispatcher.service
+    source: systemd
+    state: inactive
+    status: enabled
+NetworkManager-wait-online.service:
+    name: NetworkManager-wait-online.service
+    source: systemd
+    state: stopped
+    status: enabled
+NetworkManager.service:
+    name: NetworkManager.service
+    source: systemd
+    state: running
+    status: enabled
+auditd.service:
+    name: auditd.service
+    source: systemd
+    state: running
+    status: enabled

Note: I've only added some of the services in order to keep the simplicity The output doesn't print out any differences. It should print - symbol in front of the service name, as well as source, state and status. How can I fix my yaml?

1

There are 1 best solutions below

0
On

You'll need to loop over the task, rather than templating a loop in the after attribute. You also will probably want to run fact_diff on localhost. Maybe something like this:

- hosts: all
  become: true
  gather_facts: false
  tasks:

  - name: Gather Service Facts
    service_facts:

- hosts: localhost
  gather_facts: false
  tasks:

  - name: Show difference
    ansible.utils.fact_diff:
      before: "{{ hostvars['node0.virt'].services | to_nice_yaml }}"
      after:  "{{ hostvars[item].services | to_nice_yaml }}"
    register: result
    loop: "{{ groups.all }}"

  - copy:
      dest: services.txt
      content: |-
        {% for item in result.results %}
        === {{ item.item }} ===

        {{ item.diff_text }}
        {% endfor %}

In my test environment, I have two hosts running identical services except that one system is running darkhttpd. The inventory file look like this:

all:
  vars:
    ansible_user: root
  hosts:
    node0.virt:
    node1.virt:

And the generated services.txt file looks like:

=== node0.virt ===


=== node1.virt ===

--- before
+++ after
@@ -93,11 +93,6 @@
     source: systemd
     state: unknown
     status: static
-darkhttpd.service:
-    name: darkhttpd.service
-    source: systemd
-    state: running
-    status: enabled
 dbus-broker.service:
     name: dbus-broker.service
     source: systemd