How to loop through interface facts
Solution 1:
You came across one of the limitations of Jinja/Ansible templating, namely there is no way to evaluate expressions, which would be required to get to the value of something like ansible_{{ item }}
. You're stuck with a string.
Fortunately there is the global hostvars
object where you can access all the facts by key, which is... a string.
Something along these lines should get you there:
tasks:
- name: find interface facts
debug:
msg: "{{ hostvars[inventory_hostname]['ansible_%s' | format(item)] }}"
with_items: "{{ ansible_interfaces }}"
Solution 2:
You actually can do this.You just have to know j2 syntax pretty well, search a little bit and combine it with some hacks. DOH. just lost 2 hours. Hope I save it to someone!
It's doable like this:
- name: Display all interfaces
debug:
msg: "{{ msg.split('\n') }}"
vars:
msg: |
{% for iface in ansible_interfaces|sort %}
System interface {{ iface }}
{{ vars.ansible_facts[iface] | to_nice_json }}
{% endfor %}
And as I suspect, the people searching to do this, want to calculate the next free interface (which I was after for).
I did it like this:
- name: calc next free interface
set_fact:
nextFreeIf: "{% set ifacePrefix = vars.ansible_default_ipv4.alias %}{% set ifaceNum = { 'cnt': 0 } %}{% macro increment(dct, key, inc=1)%}{% if dct.update({key: dct[key] + inc}) %} {% endif %}{% endmacro %}{% for iface in ansible_interfaces|sort %}{% if iface| regex_search('^' ~ vars.ansible_default_ipv4.alias) %}{{ increment(ifaceNum, 'cnt') }}{% endif %}{% endfor %}{{ifacePrefix}}:{{ifaceNum.cnt}}"
the nextFreeIf is on one line, because, otherwise you get empty spaces and headaches to trim it. It's ugly, but hey, it works.
Really hope to save someones time. Cheers.