Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible nested loop over hostvars

Tags:

loops

ansible

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.

  • core_01

    ---
    ansible_host: 192.168.1.202
    site: XX-DC
    role: CORE
    model: CSR1000v 
    
    interfaces:
      - name: vlan 1
        description: "EDGE_RTR IF" 
        ipv4: 192.168.100.3/24
        state: merged
        enabled: true
    
      - name: vlan 100
        description: "IT IF"
        ipv4: 172.31.1.1/24
        state: merged
        enabled: true
    
  • core_02

    ---
    ansible_host: 192.168.12.210
    
    interfaces:
      - name: ethernet 0/0
        description: "ISP_01 IF PRIMARY"  #The discription on the interface
        ipv4: 10.0.0.2/24
        state: merged
        enabled: true
    
      - name: ethernet 0/1
        description: "CORE_SW IF PRIMARY" #The discription on the interface
        ipv4: 192.168.100.1/24
        state: merged
        enabled: true
    

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.

like image 630
notomera Avatar asked Feb 26 '26 21:02

notomera


1 Answers

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   
like image 157
β.εηοιτ.βε Avatar answered Feb 28 '26 13:02

β.εηοιτ.βε



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!