Loop over group IP's

Viewed 245

I have a group with hosts and to probe those with GlusterFS I need to turn the group into a list of IP's.

I have searched here and on Google and tried a lot of things to get this done, some include lots of code and others templates and regex and what not.

Currently I have not found a single solution to just list the IP's of a group of hosts. This is what I made myself, it takes the group, turns this dict into a list and then loops over the list, great! But when I loop over it the results are strings (why?!) and I cannot get the IP's anymore.

- name: workit
  vars:
    main_nodes_ips: "{{ groups['glusterpeers'] | list }}"
  loop: "{{ main_nodes_ips }}"
  debug:
    msg: "{{ item['hostvars'] }}"

I found this

- debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']

But how to turn it into this (example not working)

- debug: var=groups['glusterpeers']['ansible_default_ipv4']['address']

I do not understand why a list of hosts turns into a list of strings all of a sudden, but maybe I should not think of it as objects.


My Result
This is what I ended up with to probe all the peers for the GlusterFS. In the 'when' blocks I hard code the hostname of the first node, not great. I still wonder if there is not a more elegant way of probing the peers, it must be something all GlusterFS users do. Als taking the second IP may give trouble when this order of IP's changes so hostname is probably better.

- hosts: all
  gather_facts: true
  tasks:
    - set_fact:
        main_nodes_ips: "{{ groups.zicluster|
                            map('extract', hostvars, 'ansible_all_ipv4_addresses')|
                            map(attribute='1')|
                            list }}"
      run_once: true
    - debug:
        var: main_nodes_ips[1:]
      when: inventory_hostname == 'zi01'

    - name: probe the peers
      gluster.gluster.gluster_peer:
            state: present
            nodes: "{{ main_nodes_ips[1:] }}"
      when: inventory_hostname == 'zi01'
1 Answers

For example, the playbook below takes the first IP address of a remote host and creates the list

- hosts: glusterpeers
  gather_facts: true
  tasks:
    - debug:
        var: ansible_all_ipv4_addresses
    - set_fact:
        main_nodes_ips: "{{ groups.glusterpeers|
                            map('extract', hostvars, 'ansible_all_ipv4_addresses')|
                            map('first')|
                            list }}"
      run_once: true
    - debug:
        var: main_nodes_ips
      run_once: true

gives

PLAY [glusterpeers] ***************************************

TASK [Gathering Facts] ************************************
ok: [host02]
ok: [host01]
ok: [host03]

TASK [debug] **********************************************
ok: [host01] => 
  ansible_all_ipv4_addresses:
  - 10.1.0.61
ok: [host02] => 
  ansible_all_ipv4_addresses:
  - 10.1.0.62
ok: [host03] => 
  ansible_all_ipv4_addresses:
  - 10.1.0.63

TASK [set_fact] *******************************************
ok: [host01]

TASK [debug] **********************************************
ok: [host01] => 
main_nodes_ips:
  - 10.1.0.61
  - 10.1.0.62
  - 10.1.0.63

Notes

  • If you want to take any other index from the list map attribute. For example, to get the 2nd item, replace
  map('first')|

by

  map(attribute='1')|
  • In your code, you remove the first IP from the list for a particular host. This can work for the first host only
    - debug:
        msg: "{{ main_nodes_ips[1:] }}"
      when: inventory_hostname == 'host01'

Create a dictionary if you want to remove the IP for any host. e.g.

    - set_fact:
        main_nodes: "{{ dict(groups.glusterpeers|zip(main_nodes_ips)) }}"
      run_once: true

gives

  main_nodes:
    host01: 10.1.0.61
    host02: 10.1.0.62
    host03: 10.1.0.63

Then, use this dictionary to remove the IP of the particular host from the list

    - debug:
        msg: "{{ main_nodes_ips|difference(main_nodes[inventory_hostname]) }}"
      when: inventory_hostname == 'host01'

gives

TASK [debug] **************************************************
skipping: [host02]
skipping: [host03]
ok: [host01] => 
  msg:
  - 10.1.0.62
  - 10.1.0.63
Related