Nordeus / ansible_iptables_raw

iptables module for Ansible which keeps state
MIT License
127 stars 43 forks source link

Items removed from ansible role but still in state file are still executed on provision #23

Closed EvanDonato closed 6 years ago

EvanDonato commented 6 years ago

iptables_raw uses a state file that keeps items in it even if they are removed from plays. This would be fine but these items are still executed later even if an iptables -F and an rm /etc/sysconfig/iptables has been executed.

It seems that inserting items into iptables that no longer exist in any ansible plays is an undesirable behavior.

To recreate: Create a role and add an iptables_raw entry Provision Delete the original iptables_raw entry from the role and add a different one iptables -F on target rm /etc/sysconfig/iptables on target provision iptables -L will now show two entries the original one that is no longer in any plays and the new one

Since I flushed the iptables prior to running the second provision, the reasonable expectation would be that a phantom rule wouldn't appear again and that the final state of iptables should be that the only rules that are defined in an Ansible role.

This is distinct from https://github.com/Nordeus/ansible_iptables_raw/issues/13. Behavior like this is not observed in other Ansible modules including, as an easy corollary, the iptables module. The final state of iptables with the iptables module and following the above steps ends up being the beginning state (flushed) + only items that are in the Ansible plays.

Just for the sake of being thorough I also tested the same workflow above but made sure that keep_unmanaged: no was part of the play. This still caused the items that were left over in the json file to be inserted.

kustodian commented 6 years ago

That is the same thing as in #13 and it's by design. If you want to remove some rule, you have to delete it via iptables_raw module, e.g.:

- iptables_raw:
    name: rule_to_delete
    state: absent

And if you want to remove all the rules from the filter table you should also use the module:

- iptables_raw:
    name: '*'
    state: absent
EvanDonato commented 6 years ago

I understand that one shouldn't expect a rule to disappear from iptables just because it is no longer configured in ansible using iptables_raw.

The issue here however is that you can easily end up with a state where the final state of your rules is not determined by either ansible or iptables but rather through the intermediary state file that you create. If this is your stance then it might be better to describe the module as managing the state of a json file rather than iptables.

Again this behavior is NOT mirrored in other ansible modules and for something as important as iptables is a very dangerous outlook to have. It should be transparent to a user as to what the final state will be and it seems clear that that would be:

Current state of iptables with the differences from ansible applied in re: present/absent

If a user clears iptables through a flush and also removes the /etc/sysconfig/iptables file (or wherever your persistent file is located) then iptables_raw should not then add in these ghost entries. If you ignore the current state of iptables when building your dictionary it is to your peril and this seems tailored to be a gotcha for someone down the road.

kustodian commented 6 years ago

@EvanDonato I understand what you are saying and I understand that it is not ideal, but it is like it is and it's not going to change because that was the only way to make this module work. You have to learn to work with these limitations. If you want to manage iptables with this module, that means that you should only use this module to manage iptables and nothing else.

We have plans to rewrite this module (we found a workaround for the problems above), to remove the state file and with it all these limitations, but will probably write a new module and not modify this one because there will be breaking changes.