# Ansible - central firewall management

**URL:** <https://forum.ansible.com/t/ansible-central-firewall-management/5610>\
**Category:** Get Help\
**Tags:** netbox, awx\
**Created:** [May 7, 2024, 10:35pm UTC](https://forum.ansible.com/t/ansible-central-firewall-management/5610 "2024-05-07T22:35:53Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![alainseys](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/alainseys/32/2757_2.png) [@alainseys](https://forum.ansible.com/u/alainseys)\
**Post date:** [May 7, 2024, 10:35pm UTC](https://forum.ansible.com/t/ansible-central-firewall-management/5610/1 "2024-05-07T22:35:53Z")

</div>

Hello,

in our company we want to allow central firewall management all of the ansible code is in git. So the idea is to add a role where we define per host or hostgroup what rules that are applicable.

When the role is added / executed on the host it should check if any rules are appicable.  
We are using awx to to the scheduled checking.

Is there any exisiting module that does such a thing.

Tried to fiddle around with it but cant get it to work for multiple hosts bellow my attempt

handlers\main.yml

```auto
---
- name: Reload Firewall
  ansible.builtin.service:
    name: firewalld
    state: reloaded

```

tasks\main.yml

```auto
---
- name: Create Firewall rules XML files for each server
  ansible.builtin.template:
    src: "templates/firewall_rules.xml.j2"
    dest: "/etc/firewalld/services/{{ item.key }}.xml"
    mode: "0600"
  loop: "{{ firewall_ports | dict2items }}"
  when: item.key == inventory_hostname
  notify: Reload Firewall

- name: Ensure firewall rules are loaded and applied
  ansible.posix.firewalld:
    service: "{{ item.key }}"
    state: enabled
    permanent: true
    immediate: true
  loop: "{{ firewall_ports | dict2items }}"
  when: item.key == inventory_hostname
  notify: Reload Firewall

```

templates\firewall\_rules.xml.j2

```auto
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>{{ item.key }} Rules</short>
  <description>Firewall rules for {{ item.key }}</description>
  {% for port in item.value %}
  <port protocol="{{ port.split('/')[1] }}" port="{{ port.split('/')[0] }}"/>
  {% endfor %}
</service>

```

vars\main.yml

```auto
---
# vars file for firewall-management
firewall_ports:
  alain-test:
    - 443/tcp
    - 25/tcp
  NETBOX-01:
    - 80/tcp
    - 443/tcp
    - 25/tcp

```

---

<div class="post-metadata">

**Author:** ![alainseys](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/alainseys/32/2757_2.png) [@alainseys](https://forum.ansible.com/u/alainseys)\
**Post date:** [May 7, 2024, 10:36pm UTC](https://forum.ansible.com/t/ansible-central-firewall-management/5610/2 "2024-05-07T22:36:52Z")

</div>

this is the error returnd when running on multiple hosts

```auto
failed: [NETBOX-01] (item={'key': 'NETBOX-01', 'value': ['80/tcp', '443/tcp', '25/tcp']}) => {"ansible_loop_var": "item", "changed": false, "item": {"key": "NETBOX-01", "value": ["80/tcp", "443/tcp", "25/tcp"]}, "msg": "ERROR: Exception caught: org.fedoraproject.FirewallD1.Exception: INVALID_SERVICE: NETBOX-01 Permanent and Non-Permanent(immediate) operation, Services are defined by port/tcp relationship and named as they are in /etc/services (on most systems)"}

```

---

<div class="post-metadata">

**Author:** ![Leo](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/leo/32/23_2.png) [@Leo](https://forum.ansible.com/u/Leo)\
**Post date:** [November 22, 2024, 6:59pm UTC](https://forum.ansible.com/t/ansible-central-firewall-management/5610/3 "2024-11-22T18:59:38Z")

</div>

firewalld requires the `service` argument to be a valid one:

```auto

- service
        Name of a service to add/remove to/from firewalld.
        The service must be listed in output of firewall-cmd --get-
        services.
        default: null
        type: str

```

From your error, it looks like your are passing the NETBOX-01 key as that parameter.

> [@alainseys](#):
>
> INVALID\_SERVICE: NETBOX-01

If you plan on passing the ports, you should check your task to use `ports:` instead of `service:`. And you would need to fix the `item.key` in any case to pass the correct argument, as you are sending the ports label var and not the actual port or name of the services (those would be https, http, smtp for ex.)

> [@alainseys](#):
>
> ```auto
> - name: Ensure firewall rules are loaded and applied
> ansible.posix.firewalld:
> service: "{{ item.key }}"
> state: enabled
> permanent: true
> immediate: true
> loop: "{{ firewall_ports | dict2items }}"
> when: item.key == inventory_hostname
> notify: Reload Firewall
> 
> ```

Ps. came across this old post while searching for something else and thought I could contribute something before closing it
