with_subelements works where loop with subelements filter fails

178 views
Skip to first unread message

Guy Knights

unread,
Oct 11, 2018, 5:14:15 PM10/11/18
to Ansible Project
I have the following tasks in a block, which I've modified to use the new 'loop' structure:

- name: process ipv6 rules if they exist
  block
:
   
- name: create all ipv6 firewall log statements from 'firewall' variable
      iptables
:
        ip_version
: ipv6
        comment
: "{{ item.0.comment|default(omit) }}"
        destination
: "{{ item.0.destination|default(omit) }}"
        destination_port
: "{{ item.0.destination_port|default(omit) }}"
        source
: "{{ item.1 }}"
        source_port
: "{{ item.0.source_port|default(omit) }}"
        protocol
: "{{ item.0.protocol|default(omit) }}"
        jump
: "LOG"
        chain
: "{{ item.0.chain|default('INPUT') }}"
        ctstate
: "{{ item.0.state|default('NEW') }}"
        in_interface
: "{{ item.0.in_interface|default(omit) }}"
        out_interface
: "{{ item.0.out_interface|default(omit) }}"
        limit
: "3/minute"
        limit_burst
: 10
       
# log_prefix: "[ FIREWALL ] " # ( will be added in ansible 2.5 )
        state
: present
     
when: item.0.log is defined and item.0.log == 'yes'
      loop
: "{{ firewall6.rules|subelements('source') }}"
      notify
:
       
- save ip6tables

   
- name: apply ipv6 rules using 'firewall' variable defined in inventory vars
      iptables
:
        ip_version
: ipv6
        comment
: "{{ item.0.comment|default(omit) }}"
        destination
: "{{ item.0.destination|default(omit) }}"
        destination_port
: "{{ item.0.destination_port|default(omit) }}"
        source
: "{{ item.1 }}"
        source_port
: "{{ item.0.source_port|default(omit) }}"
        protocol
: "{{ item.0.protocol|default(omit) }}"
        jump
: "{{ item.0.rule|default('ACCEPT') }}"
        chain
: "{{ item.0.chain|default('INPUT') }}"
        ctstate
: "{{ item.0.state|default(omit) }}"
        in_interface
: "{{ item.0.in_interface|default(omit) }}"
        out_interface
: "{{ item.0.out_interface|default(omit) }}"
        state
: present
      loop
: "{{ firewall6.rules|subelements('source') }}"
      notify
:
       
- save ip6tables

 
when: firewall6 is defined and firewall6.rules is defined

When I run this I get the following error:

TASK [firewall : create all ipv6 firewall log statements from 'firewall' variable] *************************************
fatal
: [172.20.0.88]: FAILED! => {"msg": "obj must be a list of dicts or a nested dict"}
fatal
: [172.20.0.77]: FAILED! => {"msg": "obj must be a list of dicts or a nested dict"}
fatal
: [172.20.0.55]: FAILED! => {"msg": "obj must be a list of dicts or a nested dict"}


I changed the first task to use 'with_subelements' as follows:

    - name: create all ipv6 firewall log statements from 'firewall' variable
      iptables
:
        ip_version
: ipv6
        comment
: "{{ item.0.comment|default(omit) }}"
        destination
: "{{ item.0.destination|default(omit) }}"
        destination_port
: "{{ item.0.destination_port|default(omit) }}"
        source
: "{{ item.1 }}"
        source_port
: "{{ item.0.source_port|default(omit) }}"
        protocol
: "{{ item.0.protocol|default(omit) }}"
        jump
: "LOG"
        chain
: "{{ item.0.chain|default('INPUT') }}"
        ctstate
: "{{ item.0.state|default('NEW') }}"
        in_interface
: "{{ item.0.in_interface|default(omit) }}"
        out_interface
: "{{ item.0.out_interface|default(omit) }}"
        limit
: "3/minute"
        limit_burst
: 10
       
# log_prefix: "[ FIREWALL ] " # ( will be added in ansible 2.5 )
        state
: present
     
when: item.0.log is defined and item.0.log == 'yes'
      with_subelements
:
       
- "{{ firewall6.rules }}"
       
- source
      notify
:
       
- save ip6tables

When I re-run the playbook it now skips the task, as intended:

TASK [firewall : create all ipv6 firewall log statements from 'firewall' variable] *************************************
skipping
: [172.20.0.88]
skipping
: [172.20.0.77]
skipping
: [172.20.0.55]

Can anyone tell me why this is happening?

Thanks,
Guy


Guy Knights

unread,
Oct 11, 2018, 5:23:40 PM10/11/18
to Ansible Project
Also of note: firewall6.rules doesn't exist on any of the hosts I'm running this playbook against, so it should be skipping the entire block, but it's not.
Reply all
Reply to author
Forward
0 new messages