iterating over IPv4/IPv6 (parallel) + TCP ports (nested)

Hi,

similar to a question from about a year ago [1], I'm looking for the
best way to loop over 3 lists:

- {{ ansible_all_ipv4_addresses }}
- {{ ansible_all_ipv6_addresses | ipv6('public') }}
- tcpports

ipv4 and ipv6 IPs should iterate in parallel (I'll check that their list
lengths are matching) while tcpports should be combined in nested mode.

I guess this is a common use-case?

[1] https://groups.google.com/d/msg/ansible-devel/aLrH_SC8HyY/Zz91ifV5M-0J

similar to a question from about a year ago [1], I'm looking for the
best way to loop over 3 lists:

- {{ ansible_all_ipv4_addresses }}
- {{ ansible_all_ipv6_addresses | ipv6('public') }}
- tcpports

ipv4 and ipv6 IPs should iterate in parallel (I'll check that their list
lengths are matching) while tcpports should be combined in nested mode.

My dirty fix was to put them into a dict:

   - set_fact:
        ips:
            ipv4: "{{ item.0 }}"
            ipv6: "{{ item.1 }}"
     with_together:
        - "{{ ansible_all_ipv4_addresses }}"
        - "{{ ansible_all_ipv6_addresses }}"
     register: ips

   - set_fact: tor_ips="{{ ips.results |
map(attribute='ansible_facts.ips')|list}}"

nicer solutions are still appreciated :slight_smile:

with_items:

  • {{ ansible_all_ipv4_addresses }}
  • {{ ansible_all_ipv6_addresses | ipv6(‘public’) }}
  • tcpports

^ will flatten to single list

or you can use union to get unique single list:

with_items: “{{ tcpports|union(ansible_all_ipv4_addresses|union(ansible_all_ipv6_addresses | ipv6(‘public’)))}}”

with_items:
- {{ ansible_all_ipv4_addresses }}
- {{ ansible_all_ipv6_addresses | ipv6('public') }}
- tcpports

^ will flatten to single list

or you can use union to get unique single list:

with_items: "{{
tcpports>union(ansible_all_ipv4_addresses|union(ansible_all_ipv6_addresses
> ipv6('public')))}}"

This is not exactly what I wanted to achieve since it doesn't advance
IPv4/6 in parallel while combining that combination with every port but
the dirty workaround works and should do it.

Thanks for your reply anyway.

ah, misunderstood the question, you wan to combine the nested and together lookups (possible example):

with_nested:

  • “{{tcpports}}”
  • “{{lookup(‘together’, [ansible_all_ipv4_addresses, ansible_all_ipv6_addresses | ipv6(‘public’)] }}”

Brian Coca:

ah, misunderstood the question, you wan to combine the nested and together
lookups (possible example):

with_nested:
- "{{tcpports}}"
- "{{lookup('together', [ansible_all_ipv4_addresses,
ansible_all_ipv6_addresses | ipv6('public')] }}"

Since I certainly will need this again, I actually gave it a try, but
got this error:

Failed to template {{lookup('together', [ansible_all_ipv4_addresses,
ansible_all_ipv6_addresses]) }}: an unexpected type error occurred.
Error was sequence item 0: expected string, list found

vars:
    tcpports:
        - 1
        - 2
tasks:

   - debug: msg="going to bind to port {{ item.0 }} ipv4 {{ item.1.0 }}
ipv6 {{ item.1.1 }} "
     with_nested:
        - "{{tcpports}}"
        - "{{lookup('together', [ansible_all_ipv4_addresses,
ansible_all_ipv6_addresses]) }}"

sorry, did not test, surprised it does not take a list, maybe it has to be quoted ?

sorry, did not test, surprised it does not take a list, maybe it has to be
quoted ?

I'm not able to get this to work, if anyone is, please let me know.

There is no documentations about lookup('together', ..) on
https://docs.ansible.com/ansible/playbooks_lookups.html

I made a request for documentation here:
https://github.com/ansible/ansible/issues/14467