Ansible to add rules to firewall only if service is present

Alexander asked:

While try to describe my server in Ansible I really like the idea to form firewall rules so to enable only ports/protos that are used on host/host groups.

Imagine I have a linux based firewall box and webserver, mysql server and openvpn box behind it. As I set up webserver I apply some roles on it (http/https, ntp etc), and I’d like to add reqired ports/protos to firewall box iptables definition. And if later I disable ntp then I’d like to disable ntp-related lines in iptables for this box.

The idea is to have firewall setup connected to enabled services on boxes behind the firewall.

So the question is: is it possible to do that nice and elegant?

My answer:


I almost always build my own roles for deploying services, and I generally put the firewall rules for those services directly in the role.

Here is an example, for nginx:

In roles/nginx/tasks/firewall.yml:

- name: Open ports with system-config-securitylevel
  command: "lokkit -q -p {{item}}:tcp"
  with_items: "{{nginx_firewall_open_services}}"
  when: ansible_os_family == 'RedHat' and ansible_distribution_major_version|int == 5
  tags: firewall

- name: Open ports with system-config-firewall
  command: "lokkit -s {{item}}"
  with_items: "{{nginx_firewall_open_services}}"
  when: ansible_os_family == 'RedHat' and ansible_distribution_major_version|int == 6
  tags: firewall

- name: Open ports with firewalld
  firewalld: "service={{item}} permanent=true immediate=true state=enabled"
  with_items: "{{nginx_firewall_open_services}}"
  when: ansible_os_family == 'RedHat' and ansible_distribution_major_version|int >= 7
  tags: firewall

In roles/nginx/defaults/main.yml:

nginx_firewall_open_ports: [80, 443]
nginx_firewall_open_services: ["http", "https"]

View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.