notomera
notomera

Reputation: 81

Ansible nested loop over hostvars

I am trying to loop over all of the hosts that I've in the host_vars folder and get their corresponding interfaces, the interfaces var itself is a list.

problem: I can access the host_vars and get the desired data, except that the interface variable is a list and I want to loop over it.

What it looks like:

  1. Loop through host_vars
  2. Get the first host on the list
  3. Loop over the interfaces
  4. Repeat

To simplify things I am using debug in my example:

- name: TEST_101
  debug:
    var: 
      hostvars[item]['interfaces'][X]['name']
  loop: "{{ groups['all'] }}"

X: is the corresponding interface index

The following are two of the host_vars files.

The output when the script is run:

PLAY [Populate NetBox DataBase] ************************************************************************************************************************************************************

TASK [build_netbox_db : Create interface within Netbox with only required information] *****************************************************************************************************
ok: [localhost] => (item=edge_01) => {
    "ansible_loop_var": "item",
    "hostvars[item]['interfaces'][0]['name']": "ethernet 0/0",
    "item": "edge_01"
}
ok: [localhost] => (item=edge_02) => {
    "ansible_loop_var": "item",
    "hostvars[item]['interfaces'][0]['name']": "ethernet 0/0",
    "item": "edge_02"
}
ok: [localhost] => (item=csr1k_01) => {
    "ansible_loop_var": "item",
    "hostvars[item]['interfaces'][0]['name']": "ethernet 0/0",
    "item": "csr1k_01"
}
ok: [localhost] => (item=core_01) => {
    "ansible_loop_var": "item",
    "hostvars[item]['interfaces'][0]['name']": "vlan 1",
    "item": "core_01"
}

PLAY RECAP *********************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

X is replaced with an index number.
In a sense, I want to loop twice, once over the host, then over the interfaces of that particular host.

Upvotes: 3

Views: 5345

Answers (1)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39069

As soon as you delegate the task back to your local, then you don't need to loop on the groups['all'] anymore, and you can let Ansible do the normal process of targeting all the hosts defined in the hosts directive.

Then, you just have to loop on the interfaces variable of all hosts.

Given the playbook:

- hosts: core_01,core_02 
  ## I am limiting myslef to two hosts here, 
  ## but `all` would do just fine if you want to target all
  ## hosts in your inventory
  gather_facts: no

  tasks:
    - debug:
        msg: "{{ item.name }}"
      loop: "{{ interfaces }}"
      delegate_to: 127.0.0.1
      loop_control:
        label: "{{ item.name }}"

This will yield the recap:

PLAY [core_01,core_02] ********************************************************************************************

TASK [debug] ******************************************************************************************************
ok: [core_01] => (item=vlan 1) => 
  msg: vlan 1
ok: [core_01] => (item=vlan 100) => 
  msg: vlan 100
ok: [core_02] => (item=ethernet 0/0) => 
  msg: ethernet 0/0
ok: [core_02] => (item=ethernet 0/1) => 
  msg: ethernet 0/1

PLAY RECAP ********************************************************************************************************
core_01                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
core_02                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Upvotes: 2

Related Questions