how to compare variables on different files ansible - ansible

Hi I'm a network newbie and excuse my english it's not my native language.
Ansible version is 2.10 I wrote a playbook on show ip ospf neighbor and show ip ospf interface brief.
What I'm trying to achieve is to take out the information only about the interface from ospf neighbor and ospf interface brief(if that's possible) and compare each interface to see if they're both the same.
I'm currently using 2 switches for this playbook but this is only a prototype of a bigger network so writing the names of the interface by hand is not possible.
↓my playbook(shortened ver.)
tasks:
-------
name: sh ip ospf nei
ios_command:
commands:
- show ip ospf neighbor
register: result_ospf_neighbor
- name: sh ip ospf int br
ios_command:
commands:
- show ip ospf interface brief
register: result_ospf_interface_brief
↓result of the parse
TASK [debug result_ospf_neighbor]**********************************************
ok: [10.31.0.93] =>
msg:
- ADDRESS: 10.1.4.2
DEAD_TIME: 00:00:33
INTERFACE: FastEthernet1/0/7
NEIGHBOR_ID: 3.3.3.3
PRIORITY: '1'
STATE: FULL/BDR
- ADDRESS: 10.1.2.1
DEAD_TIME: 00:00:31
INTERFACE: FastEthernet1/0/1
NEIGHBOR_ID: 1.1.1.1
PRIORITY: '255'
STATE: FULL/DR
ok: [10.31.0.90] =>
msg:
- ADDRESS: 10.1.3.2
DEAD_TIME: 00:00:35
INTERFACE: FastEthernet1/0/5
NEIGHBOR_ID: 3.3.3.3
PRIORITY: '0'
STATE: FULL/ -
- ADDRESS: 10.1.2.2
DEAD_TIME: 00:00:36
INTERFACE: FastEthernet1/0/1
NEIGHBOR_ID: 2.2.2.2
PRIORITY: '1'
STATE: FULL/BDR
TASK [debug result_interface_brief]********************************************
ok: [10.31.0.90] =>
msg:
- AREA: '0'
COST: '1'
INTERFACE: Lo0
IP_ADDRESS_MASK: 1.1.1.1/32
NEIGHBORS_FC: 0/0
STATE: LOOP
- AREA: '0'
COST: '1'
INTERFACE: Fa1/0/5
IP_ADDRESS_MASK: 10.1.3.1/24
NEIGHBORS_FC: 1/1
STATE: P2P
- AREA: '0'
COST: '1'
INTERFACE: Fa1/0/1
IP_ADDRESS_MASK: 10.1.2.1/24
NEIGHBORS_FC: 1/1
STATE: DR
ok: [10.31.0.93] =>
msg:
- AREA: '0'
COST: '1'
INTERFACE: Lo0
IP_ADDRESS_MASK: 2.2.2.2/32
NEIGHBORS_FC: 0/0
STATE: LOOP
- AREA: '0'
COST: '1'
INTERFACE: Fa1/0/7
IP_ADDRESS_MASK: 10.1.4.1/24
NEIGHBORS_FC: 1/1
STATE: DR
- AREA: '0'
COST: '1'
INTERFACE: Fa1/0/1
IP_ADDRESS_MASK: 10.1.2.2/24
NEIGHBORS_FC: 1/1
STATE: BDR

Related

How can nest loops inside of module functions in ansible?

Hopefully I worded this question correctly.
I have a group_vars file that defines the following:
etherchannels:
access2:
- channelnumber: 1
interfaces:
- FastEthernet 1/14
- FastEthernet 1/15
access1:
- channelnumber: 1
interfaces:
- FastEthernet 1/14
- FastEthernet 1/15
And my playbook looks like this:
- name: LAN Switches
hosts: access
tasks:
- name: config unused access ports
cisco.ios.ios_lag_interfaces:
config:
- name: "{{ item.channelnumber }}"
members:
- member: "{{ item.interface }}"
mode: on
loop: "{{ etherchannels[inventory_hostname] }}"
The expected outcome is:
ansible will run through the task for each hostnames under etherchannels(access 1 and 2)
for each hostnames it would run the "name" function, defining the etherchannel and then
for each etherchannel it would run the "members" function and add every listed interface
So it would function something like this, assuming I added more etherchannels:
name: 1
members:
- member: FastEthernetX
mode: on
- member: FastEthernetY
mode: on
name: 2
members:
- member: FastEthernetZ
mode: on
- member: FastEthernetA
mode: on
I've tried to add a loop inside the "cisco.ios.ios_lag_interfaces" module command but no dice.
This looks like a job for the subelements filter. In the following example, I've wrapped your task in a debug task so that I can run it locally and demonstrate the concept:
- hosts: all
gather_facts: false
vars:
etherchannels:
access2:
- channelnumber: 1
interfaces:
- FastEthernet 1/14
- FastEthernet 1/15
access1:
- channelnumber: 1
interfaces:
- FastEthernet 1/14
- FastEthernet 1/15
tasks:
- debug:
msg: |
cisco.ios.ios_lag_interfaces:
config:
- name: "{{ item.0.channelnumber }}"
members:
- member: "{{ item.1 }}"
mode: on
loop: "{{ etherchannels[inventory_hostname]|subelements('interfaces') }}"
If I run the above playbook, the output looks like:
TASK [debug] ******************************************************************************************************************************************************************************************************
ok: [access1] => (item=[{'channelnumber': 1, 'interfaces': ['FastEthernet 1/14', 'FastEthernet 1/15']}, 'FastEthernet 1/14']) => {
"msg": "cisco.ios.ios_lag_interfaces:\n config:\n - name: \"1\"\n members:\n - member: \"FastEthernet 1/14\"\n mode: on\n"
}
ok: [access2] => (item=[{'channelnumber': 1, 'interfaces': ['FastEthernet 1/14', 'FastEthernet 1/15']}, 'FastEthernet 1/14']) => {
"msg": "cisco.ios.ios_lag_interfaces:\n config:\n - name: \"1\"\n members:\n - member: \"FastEthernet 1/14\"\n mode: on\n"
}
ok: [access1] => (item=[{'channelnumber': 1, 'interfaces': ['FastEthernet 1/14', 'FastEthernet 1/15']}, 'FastEthernet 1/15']) => {
"msg": "cisco.ios.ios_lag_interfaces:\n config:\n - name: \"1\"\n members:\n - member: \"FastEthernet 1/15\"\n mode: on\n"
}
ok: [access2] => (item=[{'channelnumber': 1, 'interfaces': ['FastEthernet 1/14', 'FastEthernet 1/15']}, 'FastEthernet 1/15']) => {
"msg": "cisco.ios.ios_lag_interfaces:\n config:\n - name: \"1\"\n members:\n - member: \"FastEthernet 1/15\"\n mode: on\n"
}
I think that's exactly what you were looking for. Your actual task would of course drop the debug wrapper:
- hosts: all
gather_facts: false
vars:
etherchannels:
access2:
- channelnumber: 1
interfaces:
- FastEthernet 1/14
- FastEthernet 1/15
access1:
- channelnumber: 1
interfaces:
- FastEthernet 1/14
- FastEthernet 1/15
tasks:
= cisco.ios.ios_lag_interfaces:
config:
- name: "{{ item.0.channelnumber }}"
members:
- member: "{{ item.1 }}"
mode: on
loop: "{{ etherchannels[inventory_hostname]|subelements('interfaces') }}"

Ansible how to loop with_dict

I want to run these mikrotik commands using ansible
interface bridge port add bridge=bridge1 ingress-filtering=no interface=ether3
interface bridge port add bridge=bridge1 ingress-filtering=no interface=ether4
BUT NOT
interface bridge port add bridge=bridge1 ingress-filtering=no interface=ether3,ether4
my playbook run wrong command
How to fix that
tq
`# cat main.yml
- hosts: mikrotiks
gather_facts: no
connection: network_cli
vars:
ansible_network_os: routeros
vlans:
- 10:
interfaces:
- ether3
- ether4
untagged_interfaces: ether2
tagged_interfaces: bridge1,ether3,ether4
network: 10.0.10.0
netmask: 24
ip_address1: 10.0.10.1
ip_address2: 10.0.10.2
dns: 192.168.88.1
dhcp_pool1: 10.0.10.101-10.0.10.150
dhcp_pool2: 10.0.10.151-10.0.10.200
leasetime: 1d
- 20:
interfaces:
- ether3
- ether4
untagged_interfaces: ether2
tagged_interfaces: bridge1,ether3,ether4
network: 10.0.20.0
netmask: 24
ip_address1: 10.0.20.1
ip_address2: 10.0.20.2
dns: 192.168.88.1
dhcp_pool1: 10.0.20.101-10.0.20.150
dhcp_pool2: 10.0.20.151-10.0.20.200
leasetime: 1d
tasks:
- import_tasks: vlan.yml
cat vlan.yml
- name: create vlans on R1
routeros_command:
commands:
- "interface bridge port add bridge=bridge1 ingress-filtering=no interface={{ item.value.interfaces }}"
- "interface bridge port add bridge=bridge1 frame-types=admit-only-untagged-and-priority-tagged pvid=10 interface={{ item.value.interfaces }}"
with_dict: "{{ vlans }}"\`
EDIT: my mikrotik commands should be like this
R1 /interface bridge port add bridge=bridge1 ingress-filtering=no interface=ether3 add bridge=bridge1 ingress-filtering=no interface=ether4 add bridge=bridge1 frame-types=admit-only-untagged-and-priority-tagged interface=ether2 pvid=10 /interface bridge vlan add bridge=bridge1 tagged=bridge1,ether3,ether4 untagged=ether2 vlan-ids=10 add bridge=bridge1 tagged=bridge1,ether3,ether4 vlan-ids=20
when I use these
\`routeros_command:
commands:
- "/interface bridge port add bridge=bridge1 ingress-filtering=no interface={{ item.1 }}"
- "/interface bridge port add bridge=bridge1 frame-types=admit-only-untagged-and-priority-tagged pvid=10 interface={{ item.1 }}"
with_subelements:
- "{{ vlans }}"
- interfaces`
I got this error
`fatal: [R1]: FAILED! => {
"msg": "could not find 'interfaces' key in iterated item '{10: {'interfaces': ['ether3', 'ether4'], 'untagged_interfaces': 'ether2', 'tagged_interfaces': 'bridge1,ether3,ether4', 'network': '10.0.10.0', 'netmask': 24, 'ip_address1': '10.0.10.1', 'ip_address2': '10.0.10.2', 'dns': '192.168.88.1', 'dhcp_pool1': '10.0.10.101-10.0.10.150', 'dhcp_pool2': '10.0.10.151-10.0.10.200', 'leasetime': '1d'}}'"`
Iterate with_subelements, e.g.
- debug:
msg: "{{ item.0.keys()|first }} ... interface={{ item.1 }}"
with_subelements:
- "{{ vlans }}"
- interfaces
gives
msg: 10 ... interface=ether3
msg: 10 ... interface=ether4
msg: 20 ... interface=ether3
msg: 20 ... interface=ether4

Trouble selecting particular entry in list

I am having a devil of a time sorting this out so any help is appreciated. I know I need to use selectattr but cannot figure out how exactly.
Using ansible I need to find the address associated with the neighbor that has a route map named BGP_TO_EC applied. I know selectattr will be involved but cannot figure out how exactly.
TIA
Parsed config:
address_family:
- afi: ipv4
neighbor:
- activate: true
address: 10.1.1.1
nexthop_self:
set: true
route_maps:
- name: BGP_TO_EC
out: true
- afi: ipv4
neighbor:
- activate: true
address: 10.2.2.2
remote_as: 3549
version: 4
network:
- address: 10.3.3.3
mask: 255.255.255.252
vrf: somevrf
Given the data
address_family:
- afi: ipv4
neighbor:
- activate: true
address: 10.1.1.1
nexthop_self:
set: true
route_maps:
- name: BGP_TO_EC
out: true
- afi: ipv4
neighbor:
- activate: true
address: 10.2.2.2
remote_as: 3549
version: 4
network:
- address: 10.3.3.3
mask: 255.255.255.252
vrf: somevrf
Simplify the data a bit. Put the below declarations into the vars as appropriate
neighbors_raw: "{{ address_family|json_query(nr_query) }}"
nr_query: "[].neighbor[].{address: address, names: route_maps[].name}"
gives
neighbors_raw:
- address: 10.1.1.1
names:
- BGP_TO_EC
- address: 10.2.2.2
names: null
Replace the null with an empty list
- set_fact:
neighbors_list: "{{ neighbors_list|d([]) +
[item|combine({'names': item.names|
ternary(item.names, [])})] }}"
loop: "{{ neighbors_raw }}"
gives
neighbors_list:
- address: 10.1.1.1
names:
- BGP_TO_EC
- address: 10.2.2.2
names: []
Now, you can select the address
- debug:
msg: "{{ neighbors_list|selectattr('names', 'contains', 'BGP_TO_EC')|
map(attribute='address')|list }}"
gives a list because, generally, there might be more selected items
msg:
- 10.1.1.1
You might want to select the first one
- debug:
msg: "{{ neighbors_list|selectattr('names', 'contains', 'BGP_TO_EC')|
map(attribute='address')|first }}"
gives
msg: 10.1.1.1

How to fetch a specific IP via vmware_guest_info?

I use vmware_guest_info: to get the DHCP address for my VMs. The problem is that after I have configured several static IP's, the guest.ipAddress is changed from the DHCP address, which is usually the first network adapter, to a randomly configured static IP:
---
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress is not none
register: gather_vm_info
delegate_to: localhost
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress != "0.0.0.0"
register: gather_vm_info
delegate_to: localhost
- debug: var=gather_vm_info.instance.guest.ipAddress
- debug: var=gather_vm_info
- name: "Update host_var with new IP Address"
set_fact:
ansible_host: "{{ gather_vm_info.instance.guest.ipAddress }}"
ansible_hostname: "{{ hostname }}"
This is what I get:
ok: [1-Europe-ECV-Site2] =>
gather_vm_info.instance.guest.net:
- _vimtype: vim.vm.GuestInfo.NicInfo
connected: true
deviceConfigId: -1
dnsConfig: null
ipAddress:
- fe80::fc70:f8ff:fe15:ae75
ipConfig:
_vimtype: vim.net.IpConfigInfo
autoConfigurationEnabled: null
dhcp: null
ipAddress:
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: fe80::fc70:f8ff:fe15:ae75
lifetime: null
origin: null
prefixLength: 64
state: unknown
macAddress: fe:70:f8:15:ae:75
netBIOSConfig: null
network: null
- _vimtype: vim.vm.GuestInfo.NicInfo
connected: true
deviceConfigId: -1
dnsConfig: null
ipAddress:
- fe80::dc8b:91ff:fefe:66dd
ipConfig:
_vimtype: vim.net.IpConfigInfo
autoConfigurationEnabled: null
dhcp: null
ipAddress:
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: fe80::dc8b:91ff:fefe:66dd
lifetime: null
origin: null
prefixLength: 64
state: unknown
macAddress: de:8b:91:fe:66:dd
netBIOSConfig: null
network: null
- _vimtype: vim.vm.GuestInfo.NicInfo
connected: true
deviceConfigId: -1
dnsConfig: null
ipAddress:
- fe80::f8ea:c4ff:fe90:99e2
ipConfig:
_vimtype: vim.net.IpConfigInfo
autoConfigurationEnabled: null
dhcp: null
ipAddress:
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: fe80::f8ea:c4ff:fe90:99e2
lifetime: null
origin: null
prefixLength: 64
state: unknown
macAddress: fa:ea:c4:90:99:e2
netBIOSConfig: null
network: null
- _vimtype: vim.vm.GuestInfo.NicInfo
connected: true
**deviceConfigId: 4000**
dnsConfig: null
ipAddress:
- 192.168.0.35
- fe80::250:56ff:fe91:c8c0
ipConfig:
_vimtype: vim.net.IpConfigInfo
autoConfigurationEnabled: null
dhcp: null
ipAddress:
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: 192.168.0.35
lifetime: null
origin: null
prefixLength: 16
state: preferred
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: fe80::250:56ff:fe91:c8c0
lifetime: null
origin: null
prefixLength: 64
state: unknown
It looks like that VMWare assigned deviceConfigId: 4000 for the first Network Interface, but how can I access it on my Playbook?
debug: var=gather_vm_info.instance.guest.net[3].ipAddress[0]-?????
EDIT:
Can somebody explain, why vSphere register the IP address correctly for some VM's as guest.ipAddress and sometimes you have to get it as gather_vm_info.instance.hw_eth0.ipaddresses.
This would be fine, but in this example you can see that the IPAddress is only registered as gather_vm_info.instance.hw_eth0.ipaddresses and you don't get it as hw_eth0.ipaddresses???
TASK [debug] ******************************************************************************************************************************************************************************
ok: [1-USA-ECV-Site8] =>
gather_vm_info:
changed: false
failed: false
instance:
annotation: Silver Peak Systems ECV
current_snapshot: null
customvalues: {}
guest_consolidation_needed: false
guest_question: null
guest_tools_status: guestToolsRunning
guest_tools_version: '10341'
hw_cluster: null
hw_cores_per_socket: 1
hw_datastores:
- Datastore2
hw_esxi_host: 51.89.43.64
hw_eth0:
addresstype: assigned
ipaddresses: null <<-- IP Address is missing!?
label: Network adapter 1
macaddress: 00:50:56:91:55:12
macaddress_dash: 00-50-56-91-55-12
portgroup_key: null
portgroup_portkey: null
summary: Management
hw_eth1:
addresstype: assigned
ipaddresses: null
label: Network adapter 2
macaddress: 00:50:56:91:26:a1
macaddress_dash: 00-50-56-91-26-a1
portgroup_key: null
portgroup_portkey: null
summary: 1-MPLS
hw_eth2:
addresstype: assigned
ipaddresses:
- 10.8.10.1
- fe80::250:56ff:fe91:361d
label: Network adapter 3
macaddress: 00:50:56:91:36:1d
macaddress_dash: 00-50-56-91-36-1d
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_eth3:
addresstype: assigned
ipaddresses: null
label: Network adapter 4
macaddress: 00:50:56:91:b7:ce
macaddress_dash: 00-50-56-91-b7-ce
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_eth4:
addresstype: assigned
ipaddresses: null
label: Network adapter 5
macaddress: 00:50:56:91:68:73
macaddress_dash: 00-50-56-91-68-73
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_eth5:
addresstype: assigned
ipaddresses:
- fe80::250:56ff:fe91:b5c8
label: Network adapter 6
macaddress: 00:50:56:91:b5:c8
macaddress_dash: 00-50-56-91-b5-c8
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_eth6:
addresstype: assigned
ipaddresses: null
label: Network adapter 7
macaddress: 00:50:56:91:83:ab
macaddress_dash: 00-50-56-91-83-ab
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_files:
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8.vmx'
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8.nvram'
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8.vmsd'
- '[Datastore2] 1-USA-ECV-Site8/vmware.log'
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8.vmdk'
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8_1.vmdk'
hw_folder: /OVH/vm
hw_guest_full_name: Other 4.x or later Linux (64-bit)
hw_guest_ha_state: null
hw_guest_id: other4xLinux64Guest
hw_interfaces:
- eth0
- eth1
- eth2
- eth3
- eth4
- eth5
- eth6
hw_is_template: false
hw_memtotal_mb: 4096
hw_name: 1-USA-ECV-Site8
hw_power_status: poweredOn
hw_processor_count: 2
hw_product_uuid: 4211ed87-aa18-53bb-a983-7aff188b115a
hw_version: vmx-14
instance_uuid: 5011fd96-b512-e3d1-d6f0-ac58201e75db
ipv4: 192.168.0.212 <<-- IP Address is only assigned here!?
ipv6: null
module_hw: true
moid: vm-2296
snapshots: []
vimref: vim.VirtualMachine:vm-2296
vnc: {}
IP Address of the first interface can get through the hw_eth0 property of the vmware_guest_info module result.
Here's the sample playbook.
---
- name: Example Playbook
hosts: localhost
gather_facts: false
vars:
hostname: test_vm2
tasks:
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
register: gather_vm_info
- name: Display the first interface set IP Address of a virtual machine
debug:
msg: >-
{{ gather_vm_info.instance.hw_eth0.ipaddresses
| map('ipaddr', 'ipv4')
| select('!=', false)
| list
| first
}}
The hw_eth0 is the interface information of a virtual machine have.
If you want to get the second interface IP Address, change from hw_eth0 to hw_eth1.
The above playbook uses the ipaddr filter in getting only ipv4 address.
So it needs to install netaddr library.
(venv)$ pip install netaddr
By the way, the following playbook can be possible to get the first interface IP Address too.
---
- name: Example Playbook
hosts: localhost
gather_facts: false
hostname: test_vm2
tasks:
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.net
register: gather_vm_info
- name: Set device_config_ids variable
set_fact:
device_config_ids: >-
{{ device_config_ids | default([])
+ [item.deviceConfigId]
}}
loop: "{{ gather_vm_info.instance.guest.net }}"
- name: Display the first interface set IP Address of a virtual machine
debug:
msg: "{{ item.1.ipAddress.0 }}"
with_nested:
- "{{ device_config_ids | sort | first }}"
- "{{ gather_vm_info.instance.guest.net }}"
when:
- item.0 | int == item.1.deviceConfigId

get child elements of a dictonairy

I have a network with different hosts and different networks and I want to use ansible to ping each host in each network.
In my host_vars directory all informations about every host and its network are stored in its own file. A hostfile looks like this:
bond:
- conn_name: net1
ip4: '10.10.44.21'
gw4: '10.10.44.1'
- conn_name: net2
ip4: '10.10.47.21'
gw4: '10.10.47.1'
- conn_name: net3
ip4: '10.10.46.21'
gw4: '10.10.46.1'
bond_slave:
- conn_name: eno1
ifname: eno1
master: net1
- conn_name: eno2
ifname: eno2
master: net2
- conn_name: ens2f1
ifname: ens2f1
master: net2
- conn_name: ens2f0
ifname: ens2f0
master: net2
- conn_name: ens4f1
ifname: ens4f1
master: net3
- conn_name: ens4f0
ifname: ens4f0
master: net3
My purpose is to get every ip4-value and ping it from every host. what i can do is include all files from host_vars directory and ping the ip-adress of the first bond item of each file.
---
- hosts: all
- name: Include information about all hosts
include_vars: ../../host_vars/{{ item }}.yaml
with_items: hosts
register: "r"
- name: execute ping
command: ping {{ bond[0].ip4 }} -c 3
with_items: "{{ r.results }}"
But the bond can have from 2 to 4 networks. How do i loop through each bond to access all ip-address?
Solution
Even though the snippet of Konstantin Suvorov wasn't working for me, it helped me to find the right solution:
- name: execute ping
command: ping {{ item.ip4 }} -c 3
with_items: "{{ r.results | map(attribute='ansible_facts.bond') | list }}"
If you have bond var defined for each host via host_vars, you can use hostvars magic variable (no need to do this ugly include task):
- name: ping everything
command: ping {{ item }} -c 3
with_items: "{{ play_hosts | map('extract',hostvars,'bond') | list }}"
Actually this Jinja2 expression will return a list of lists, but with_items flattends them, so you end up with long list all elements from every bond of every host in current play.

Resources