1

Hope you are fine.

I am still in trouble with looping over ansible 2.9 facts despites my search on web and documentation.

I woul like to retrieve ip address from custom interfaces on all hosts and put in a list. This is what i tried:

---
- hosts: all
  gather_facts: True
  vars:
    ip_private_list: []

    - set_fact:
        ip_private_list: "{{  ip_private_list + [item]  }}"
      with_items: "{{ hostvars[inventory_hostname]['ansible_ens256']['ipv4']['address'] }}"
      delegate_facts: true

I don't understand why ip_private_list is not populated with elements and when i try to debug with msg i get "Ansible Undefined"

Is there anything i miss about data structure or the right way to do it ?

Thans for you help

1 Answer 1

0

This query should give you the list of the IP addresses

    - set_fact:
        ipl: "{{ hostvars|dict2items|
                 json_query('[].value[].ansible_ens256.ipv4[].address') }}"
      run_once: true

Notes

Map the hosts and extract the variables from hostvars. For example

shell> cat playbook.yml
- hosts: test_11,test_12,test_13
  tasks:
    - set_fact:
        ipv4_dict: "{{ dict(ansible_play_hosts|zip(_ipv4)) }}"
      vars:
        _ipv4: "{{ ansible_play_hosts|
                   map('extract', hostvars, ['ansible_wlan0', 'ipv4'])|
                   list }}"
      run_once: true

gives the dictionary of lists

  ipv4_dict:
    test_11:
    - address: 10.1.0.61
      broadcast: 10.1.0.61
      netmask: 255.255.255.255
      network: 10.1.0.61
    test_12:
    - address: 10.1.0.62
      broadcast: 10.1.0.62
      netmask: 255.255.255.255
      network: 10.1.0.62
    test_13:
    - address: 10.1.0.63
      broadcast: 10.1.0.63
      netmask: 255.255.255.255
      network: 10.1.0.63

The values of the dictionary are lists because the maybe more IP addresses associated with an adapter. Use this dictionary to select the IP addresses, e.g.

    - set_fact:
        ipv4_address: "{{ dict(ansible_play_hosts|zip(_address)) }}"
      vars:
        _address: "{{ ipv4_dict|dict2items|json_query('[].value[].address') }}"
      run_once: true

gives the dictionary

  ipv4_address:
    test_11: 10.1.0.61
    test_12: 10.1.0.62
    test_13: 10.1.0.63

If you want a simple list of the IP addresses select the values of the dictionary, e.g.

    - set_fact:
        ip_private_list: "{{ ipv4_address.values()|list }}"
      run_once: true

gives

  ip_private_list:
  - 10.1.0.61
  - 10.1.0.62
  - 10.1.0.63
1
  • Wow ! I think my lack of python knowledge is disturbing ! Thank you very much for your help and the answer :), i have to get a deep dive on filters and functions by the way
    – Mandala
    May 5, 2021 at 14:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .