Strange iptables_raw + with_together behaviour

Hi all

Ive come across a quirk when using the ‘iptables_raw’ module along with the ‘with_together’ loop.
Logically, im inserting three new iptables input rules (for ftp) and giving them a name
I would expect that with_together would assign a name to a rule in the order that they appear in a list,
e.g. [a, b, c]
[1, 2, 3]
= a1, b2, c3

`

Ansible task

  • name: Create iptables rules for ftp access
    iptables_raw:
    name: ‘ftp_{{ item.0 }}’
    rules: “{{ item.1 }}”
    with_together:
  • { connection,
    data,
    passive }
  • { ‘-A INPUT -p tcp --dport 21 -j ACCEPT’,
    ‘-A INPUT -p tcp --dport 20 -j ACCEPT’,
    ‘-A INPUT -p tcp -m tcp --sport 1024: --dport 1024: -m conntrack --ctstate ESTABLISHED -j ACCEPT’ }

`

`

Result on target machine

Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp – 0.0.0.0/0 0.0.0.0/0 tcp spts:1024:65535 dpts:1024:65535 ctstate ESTABLISHED /* ansible[ftp_data] /
2 ACCEPT tcp – 0.0.0.0/0 0.0.0.0/0 tcp dpt:21 /
ansible[ftp_connection] /
3 ACCEPT tcp – 0.0.0.0/0 0.0.0.0/0 tcp dpt:20 /
ansible[ftp_passive] */

`

The expected output is:
port 21 - connection
port 20 - data
spts:1024:65535 dpts:1024:65535 - passive

Peculiarly, it doesn’t matter what order either list is in, the result is the same.

(Another quirk of the iptables_raw module is that the -A flag inserts at the top of the list
instead of appending to the end, different to creating a rule from the command line,
where -I is used to insert at the top of the list and -A appends to the end.)

Ansible version 2.2.0.0
ansible host: centos 6.8
target: centos 7.2

Since I’m working with a centos7 box I’ve gone back to firewalld as a workaround.

I understand the iptables_raw module isn’t widely used and there exists an iptables module.

Hi all

Ive come across a quirk when using the 'iptables_raw' module along with the
'with_together' loop.
Logically, im inserting three new iptables input rules (for ftp) and giving
them a name
I would expect that with_together would assign a name to a rule in the
order that they appear in a list,

It will when you use a list and not dictionary as you using bellow.
Dictionary is unordered in Python.

# Ansible task
- name: Create iptables rules for ftp access
  iptables_raw:
    name: 'ftp_{{ item.0 }}'
    rules: "{{ item.1 }}"
  with_together:
    - { connection,
        data,
        passive }
    - { '-A INPUT -p tcp --dport 21 -j ACCEPT',
        '-A INPUT -p tcp --dport 20 -j ACCEPT',
        '-A INPUT -p tcp -m tcp --sport 1024: --dport 1024: -m conntrack
--ctstate ESTABLISHED -j ACCEPT' }

# Result on target machine
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp
spts:1024:65535 dpts:1024:65535 ctstate ESTABLISHED /* ansible[ftp_data] */
2 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp
dpt:21 /* ansible[ftp_connection] */
3 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp
dpt:20 /* ansible[ftp_passive] */

The expected output is:
port 21 - connection
port 20 - data
spts:1024:65535 dpts:1024:65535 - passive

Peculiarly, it doesn't matter what order either list is in, the result is
the same.

You say list but are using {} instead of , I guess you will get correct result when you change to use lists.