# ansible\_facts showing interface eth0\_1

**URL:** <https://forum.ansible.com/t/ansible-facts-showing-interface-eth0-1/37547>\
**Category:** Ansible Project\
**Created:** [January 12, 2023, 11:24am UTC](https://forum.ansible.com/t/ansible-facts-showing-interface-eth0-1/37547 "2023-01-12T11:24:49Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kathy\_L](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kathy_l/32/2652_2.png) [@Kathy\_L](https://forum.ansible.com/u/Kathy_L)\
**Post date:** [January 12, 2023, 11:24am UTC](https://forum.ansible.com/t/ansible-facts-showing-interface-eth0-1/37547/1 "2023-01-12T11:24:49Z")

</div>

I’m using ansible-core 1.18. When I gather facts on a device, it shows the interfaces of eth0, eth0\_1, eth1 and lo. The results of “ip a” show only eth0, eth1 and lo interfaces . When I try to start arpwatch for each interface (other than lo), it fails on eth0\_1, which makes sense to me. Why does ansible\_facts interfaces show eth0\_1?

---

<div class="post-metadata">

**Author:** ![SP1\_77](https://avatars.discourse-cdn.com/v4/letter/s/5e9695/32.png) [@SP1\_77](https://forum.ansible.com/u/SP1_77)\
**Post date:** [January 17, 2023, 2:43am UTC](https://forum.ansible.com/t/ansible-facts-showing-interface-eth0-1/37547/2 "2023-01-17T02:43:45Z")

</div>

Hi 👋

It’s the VLAN ID for the sub-interface which ansible\_facts is showing for eth0\_1

You must use the iproute 2 package with ip addr not net-tools

If you want to modify this then you will need set\_facts magic;

To access variables of other hosts, you should enable [fact caching](http://docs.ansible.com/ansible/playbooks_variables.html#fact-caching).

In playbook files, you should adding `gather_facts: True` to update facts.

The `ansible_interfaces` fact lists all of the existing network interfaces.

Some hints to get an interface when you know more information:

```auto
    var:
      allNetworkInterfaces: "{{ ansible_facts | dict2items | selectattr('value.ipv4', 'defined') | map(attribute='value') | list }}"
      allNetworkInterfaces_variant2: "{{ ansible_facts.interfaces | map('extract', ansible_facts ) | list }}"
      interfaceWithKnownIp: "{{ ansible_facts | dict2items | selectattr('value.ipv4', 'defined') | selectattr('value.ipv4.address', 'equalto', myKnowIpV4) | first }}"
      interfaceWithKnownIp_fromVar: "{{ allNetworkInterfaces | selectattr('ipv4.address', 'equalto', myKnowIpV4) | first }}"
      interfacesWithPartialKnowMac: "{{ allNetworkInterfaces | selectattr('macaddress', 'match', knownMacPrefix~'.*') | list }}"
      interfacesWitKnowType: "{{ allNetworkInterfaces | selectattr('type', 'equalto', knownType) | sort(attribute='device') | list }}"
      # extended on 2020-10-28
      queryForKnownIpv6: "[*].{device: device, ipv4: ipv4, ipv6: ipv6[? address == 'fe80::a00:27ff:fe38:ad36']}[?ipv6])" # string must be in ' # sorry, only partial interface info, did not find out how to return all info directly
      interfacesWithKnownIpv6: '{{ allNetworkInterfaces | json_query(queryForKnownIpv6) | first }}'
      queryForKnownIpv4_linux: "[?ipv4.address == '{{ myKnownIpV4 }}']}[?ipv4])" # string must be in '
      interfacesWithKnownIp_variantJsonQuery: '{{ allNetworkInterfaces | json_query(queryForKnownIpv4_linux) | first }}'

```

some short explications:

- [dict2item](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#dict-filter) because [selectattr](http://jinja.pocoo.org/docs/dev/templates/#selectattr)expects an array
- [map(attribute=‘…’)](http://jinja.pocoo.org/docs/dev/templates/#map) to unpack this array
- [map(‘extract’, …)](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#extracting-values-from-containers) to extract interfaces from `ansible_facts`
- `ansible_facts.interfaces` is the same as `ansible_interfaces`
- [json\_query()](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#selecting-json-data-json-queries) for flexible selecting and unpacking, an alternative variant with `map()? is welcome

the `ansible_interfaces` fact contains a list of all the network interfaces and they appear to be in order (i.e., the first ethernet interface would have been called eth0, the second eth1, etc). With a little `set_fact` magic:

```auto
- name: define traditional ethernet facts
  set_fact:
    ansible_eth: "{% set ansible_eth = ansible_eth|default([]) + [hostvars[inventory_hostname]['ansible_' + item]] %}{{ ansible_eth|list }}"
  when: hostvars[inventory_hostname]['ansible_' + item]['type'] == 'ether'
  with_items:
    - "{{ hostvars[inventory_hostname]['ansible_interfaces'] }}"

```

This loops over all of the `ansible_interfaces` entries for the current machine and builds a list of the `hostvars[inventory_hostname]['ansible_' + item]` entries that have a `type` equal to “ether”.

Thus now `ansible_eth.0` and `ansible_eth.1` should be roughly equivalent to the old `ansible_eth0`` and ``ansible_eth1` respectively.

Best,

S.W

---

<div class="post-metadata">

**Author:** ![SP1\_77](https://avatars.discourse-cdn.com/v4/letter/s/5e9695/32.png) [@SP1\_77](https://forum.ansible.com/u/SP1_77)\
**Post date:** [January 17, 2023, 8:45am UTC](https://forum.ansible.com/t/ansible-facts-showing-interface-eth0-1/37547/3 "2023-01-17T08:45:17Z")

</div>

Hi 👋

It’s the VLAN ID for the sub-interface which ansible\_facts is showing for eth0\_1

You must use the iproute 2 package with ip addr not net-tools

If you want to modify this then you will need set\_facts magic;

To access variables of other hosts, you should enable [fact caching](http://docs.ansible.com/ansible/playbooks_variables.html#fact-caching).

In playbook files, you should add in:

gather\_facts: True

#to update facts.

The ansible\_interfaces fact lists all of the existing network interfaces.

Some hints to get an interface when you know more information:

var:

allNetworkInterfaces: “{{ ansible\_facts | dict2items | selectattr(‘value.ipv4’, ‘defined’) | map(attribute=‘value’) | list }}”

allNetworkInterfaces\_variant2: “{{ ansible\_facts.interfaces | map(‘extract’, ansible\_facts ) | list }}”

interfaceWithKnownIp: “{{ ansible\_facts | dict2items | selectattr(‘value.ipv4’, ‘defined’) | selectattr(‘value.ipv4.address’, ‘equalto’, myKnowIpV4) | first }}”

interfaceWithKnownIp\_fromVar: “{{ allNetworkInterfaces | selectattr(‘ipv4.address’, ‘equalto’, myKnowIpV4) | first }}”

interfacesWithPartialKnowMac: “{{ allNetworkInterfaces | selectattr(‘macaddress’, ‘match’, knownMacPrefix~‘.\*’) | list }}”

interfacesWitKnowType: “{{ allNetworkInterfaces | selectattr(‘type’, ‘equalto’, knownType) | sort(attribute=‘device’) | list }}”

# extended on 2020-10-28

queryForKnownIpv6: “[\*].{device: device, ipv4: ipv4, ipv6: ipv6[? address == ‘fe80::a00:27ff:fe38:ad36’]}[?ipv6])” # string must be in ’ # sorry, only partial interface info, did not find out how to return all info directly

interfacesWithKnownIpv6: ‘{{ allNetworkInterfaces | json\_query(queryForKnownIpv6) | first }}’

queryForKnownIpv4\_linux: “[?ipv4.address == ‘{{ myKnownIpV4 }}’]}[?ipv4])” # string must be in ’

interfacesWithKnownIp\_variantJsonQuery: ‘{{ allNetworkInterfaces | json\_query(queryForKnownIpv4\_linux) | first }}’

some short explications:

- [dict2item](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#dict-filter) because [selectattr](http://jinja.pocoo.org/docs/dev/templates/#selectattr) expects an array
- [map(attribute=‘…’)](http://jinja.pocoo.org/docs/dev/templates/#map) to unpack this array
- [map(‘extract’, …)](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#extracting-values-from-containers) to extract interfaces from ansible\_facts
- ansible\_facts.interfaces is the same as ansible\_interfaces
- [json\_query()](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#selecting-json-data-json-queries) for flexible selecting and unpacking, an alternative variant with `map()? is welcome

the ansible\_interfaces fact contains a list of all the network interfaces and they appear to be in order (i.e., the first ethernet interface would have been called eth0, the second eth1, etc). With a little set\_fact magic:

- name: define traditional ethernet facts

set\_fact:

ansible\_eth: “{% set ansible\_eth = ansible\_eth|default() + [hostvars[inventory\_hostname][‘ansible\_’ + item]] %}{{ ansible\_eth|list }}”

when: hostvars[inventory\_hostname][‘ansible\_’ + item][‘type’] == ‘ether’

with\_items:

- “{{ hostvars[inventory\_hostname][‘ansible\_interfaces’] }}”

This loops over all of the ansible\_interfaces entries for the current machine and builds a list of the hostvars[inventory\_hostname][‘ansible\_’ + item] entries that have a type equal to “ether”.

Thus now ansible\_eth.0 and ansible\_eth.1 should be roughly equivalent to the old ansible\_eth0 and ansible\_eth1 respectively.

Best,

S.W

---

<div class="post-metadata">

**Author:** ![Kathy\_L](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kathy_l/32/2652_2.png) [@Kathy\_L](https://forum.ansible.com/u/Kathy_L)\
**Post date:** [January 17, 2023, 12:10pm UTC](https://forum.ansible.com/t/ansible-facts-showing-interface-eth0-1/37547/4 "2023-01-17T12:10:20Z")

</div>

Thanks for that info - very interesting.

I’m trying to start arpwatch for each interface using the following:

name: Start arpwatch  
command: arpwatch -i {{ item }}  
loop: “{{ ansible\_interfaces }}”  
when: ansible\_facts[item] is defined and not ‘lo’

I need to provide for eth interfaces as well as ens192… etc. Any idea what I can do to ignore these VLAN interfaces?

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [January 17, 2023, 3:03pm UTC](https://forum.ansible.com/t/ansible-facts-showing-interface-eth0-1/37547/5 "2023-01-17T15:03:57Z")

</div>

Kathy, your “when:” condition is incorrect. “not ‘lo’” will always be false, so likewise

```auto
  when: ansible_facts[item] is defined and not 'lo'

```

will also always be false.

---

<div class="post-metadata">

**Author:** ![Kathy\_L](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kathy_l/32/2652_2.png) [@Kathy\_L](https://forum.ansible.com/u/Kathy_L)\
**Post date:** [January 18, 2023, 7:35pm UTC](https://forum.ansible.com/t/ansible-facts-showing-interface-eth0-1/37547/6 "2023-01-18T19:35:59Z")

</div>

That makes sense -thank you. Sorry for the confusion - some of your text is white and did not display against my white background! It works now!
