I have this list of firwalld zones to configure:
fw_zones:
- name: "example"
target: "DROP"
allowed_services:
- ssh
icmp_block_inversion: true
icmp_blocks:
- fragmentation-needed
- name: "another_example"
target: "DROP"
allowed_services:
- ssh
- http
- ntp
icmp_block_inversion: true
icmp_blocks:
- fragmentation-needed
- echo-request
and I want to use the firewalld
module to do so. While setting new zones shouldn't be a problem, and setting their default target can probably only be done using command
module, I am struggling to find a solution for enabling services/icmp blocks since I'm already iterating over a list (fw_zones
). Is there a straightforward solution to achieving this?
I tried different setups of this list, like:
fw_zones:
example:
target: "DROP"
allowed_services:
- ssh
icmp_block_inversion: true
icmp_blocks:
- fragmentation-needed
another_example:
target: "DROP"
allowed_services:
- ssh
- http
- ntp
icmp_block_inversion: true
icmp_blocks:
- fragmentation-needed
- echo-request
and using | dict2items
, but in all cases I couldn't figure out how to iterate over the icmp_blocks
and allowed_services
lists.
What you're looking for is nested loops.
While the recommendation is to construct the data in a way that avoids nested loops, it's obvious that sometimes it will make the maintenance of the data complicated, like in your case.
So, you can either run the loop over some product
of your list, or use the nested include_tasks
. In my opinion, the difference would be that using product
could be more elegant, but nested tasks are more straightforward.
So, given your initial list, you can do something like the following:
# playbook.yaml
---
- name: Manage the firewalld settings
hosts: all
tasks:
- name: Looping over the zones
include_tasks: firewalld_zones_loop.yaml
loop: "{{ fw_zones }}"
loop_control:
loop_var: fw_zone
# firewalld_zones_loop.yaml
---
- name: Looping over the services
include_tasks: firewalld_services_loop.yaml
loop: "{{ fw_zone.allowed_services }}"
loop_control:
loop_var: fw_service
# firewalld_services_loop.yaml
---
- name: Set the firewall rule
firewalld:
zone: "{{ fw_zone.name }}"
target: "{{ fw_zone.target }}"
service: "{{ fw_service }}"
icmp_block: "{{ fw_icmp_block }}"
state: enabled
# ...
loop_control:
loop_var: fw_icmp_block