Collect together the results of all hosts

Hi,

How can I with ansible collect all results not only from one host but from all and put together in a file (template)?

Here’s below my playbook and jinja2 config’s files :

---
- name: Get all interfaces
  hosts: fedora
  gather_facts: false
  remote_user: ansible
  vars:
    all_hosts_interfaces: {}

  tasks:
    - name: Get all interfaces of hosts
      raw: "nmcli con show | sed '1 d' | awk '{print $1}'"
      register: nmcli_ports

    - name: Create dict of interfaces
      set_fact:
        all_hosts_interfaces: "{{ dict([['host_name', inventory_hostname],['int_name', nmcli_ports.stdout_lines]]) }}"
    
    - name: Create file with template
      template:
        src: all_int_report4.j2
        dest: "all_int_report4.txt"
      delegate_to: localhost
      vars:
        all_interfaces: "{{ all_hosts_interfaces }}"
# Create by ansible
# ========================================

hostname : {{ all_interfaces.host_name }}
{% for item in all_interfaces.int_name %}
  net: {{ item }}
{% endfor %}

Here’s the result that I got:

# Create by ansible
# ========================================

hostname : x.x.x.x
  net: ens160
  net: lo

and what I’d like to get:

# Create by ansible
# ========================================

hostname : x.x.x.w
  net: ens160
  net: lo
hostname : x.x.x.y
  net: ens160
  net: lo
hostname : x.x.x.x
  net: ens160
  net: lo
hostname : x.x.x.z
  net: ens160
  net: lo

if I understand correctly, the creation of the dict is renewed for each host, so there won’t be any append to the dict. the values will always be those of the last hosts

I think Ansible isn’t designed for this kind of thing and I need to find another solution, or do you have any idea?

You can definitely do this with Ansible.
Template:

{{ ansible_managed | comment }}

{% for host in ansible_play_hosts %}
hostname : {{ host }}
{% for item in hostvars[host]['all_hosts_interfaces']['int_name'] %}
  net: {{ item }}
{% endfor %}
{% endfor %}

Task:

    - name: Create file with template
      ansible.builtin.template:
        src: all_int_report4.j2
        dest: "all_int_report4.txt"
      delegate_to: localhost
      run_once: true
2 Likes

Thank you for your quick answer… yeah it’s running well :wink:
Is it because you call the hostvars variable? In other words, you loop through all the hosts, instead only of variable like my example?
Apart the run_once I see only this difference.

1 Like

Good question.

{% for host in ansible_play_hosts %} will loop through all the hosts in the playbook and then you can use hostvars to access variables that belong to the hosts.

With this approach, you only want to run the task once, so I use run_once in conjunction with delegate_to: localhost to achieve this.

1 Like

You might also want to consider replacing ansible.builtin.raw with ansible.builtin.shell, unless your hosts does not have Python installed.

2 Likes