AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible firewalld & ufw Modules: Manage Firewall Rules (Complete Guide)

By Luca Berton · Published 2024-01-01 · Category: installation

Complete guide to Ansible firewalld and ufw modules. Open ports, allow services, manage zones, configure rich rules, set up NAT, and manage firewall state.

Ansible manages Linux firewalls through two modules: ansible.posix.firewalld for RHEL/CentOS/Fedora (firewalld) and community.general.ufw for Ubuntu/Debian (UFW). Both let you open ports, allow services, and manage firewall state idempotently.

firewalld Module (RHEL/CentOS/Fedora)

Open a Port

- name: Open HTTP port
  ansible.posix.firewalld:
    port: 80/tcp
    permanent: true
    immediate: true
    state: enabled

- name: Open multiple ports ansible.posix.firewalld: port: "{{ item }}" permanent: true immediate: true state: enabled loop: - 80/tcp - 443/tcp - 8080/tcp

Allow a Service

- name: Allow HTTPS service
  ansible.posix.firewalld:
    service: https
    permanent: true
    immediate: true
    state: enabled

# List available services: firewall-cmd --get-services - name: Allow common services ansible.posix.firewalld: service: "{{ item }}" permanent: true immediate: true state: enabled loop: - http - https - ssh - postgresql

Manage Zones

# Add interface to zone
- name: Assign eth1 to internal zone
  ansible.posix.firewalld:
    zone: internal
    interface: eth1
    permanent: true
    immediate: true
    state: enabled

# Allow service in specific zone - name: Allow PostgreSQL in internal zone ansible.posix.firewalld: service: postgresql zone: internal permanent: true immediate: true state: enabled

Rich Rules

# Allow from specific IP
- name: Allow monitoring server
  ansible.posix.firewalld:
    rich_rule: 'rule family="ipv4" source address="10.0.1.100" port port="9090" protocol="tcp" accept'
    permanent: true
    immediate: true
    state: enabled

# Rate limit SSH - name: Rate limit SSH connections ansible.posix.firewalld: rich_rule: 'rule service name="ssh" accept limit value="10/m"' permanent: true immediate: true state: enabled

# Block an IP - name: Block malicious IP ansible.posix.firewalld: rich_rule: 'rule family="ipv4" source address="192.168.1.100" reject' permanent: true immediate: true state: enabled

Port Forwarding

- name: Forward port 8080 to 80
  ansible.posix.firewalld:
    rich_rule: 'rule family="ipv4" forward-port port="8080" protocol="tcp" to-port="80"'
    permanent: true
    immediate: true
    state: enabled

Source-Based Rules

- name: Allow subnet
  ansible.posix.firewalld:
    source: 10.0.0.0/24
    zone: trusted
    permanent: true
    immediate: true
    state: enabled

See also: Ansible firewalld Module: Open Firewall Ports on RHEL/CentOS (Examples)

UFW Module (Ubuntu/Debian)

Open a Port

- name: Allow SSH
  community.general.ufw:
    rule: allow
    port: '22'
    proto: tcp

- name: Allow HTTP and HTTPS community.general.ufw: rule: allow port: "{{ item }}" proto: tcp loop: - '80' - '443'

Enable UFW

# Default deny incoming, allow outgoing
- name: Set default policies
  community.general.ufw:
    default: deny
    direction: incoming

- name: Allow outgoing community.general.ufw: default: allow direction: outgoing

- name: Enable UFW community.general.ufw: state: enabled

Allow from Specific IP

- name: Allow from monitoring server
  community.general.ufw:
    rule: allow
    from_ip: 10.0.1.100
    port: '9090'
    proto: tcp

# Allow entire subnet - name: Allow internal network community.general.ufw: rule: allow from_ip: 10.0.0.0/24

Rate Limiting

# Limit SSH connections (deny if >6 attempts in 30 seconds)
- name: Rate limit SSH
  community.general.ufw:
    rule: limit
    port: '22'
    proto: tcp

Delete a Rule

- name: Remove rule
  community.general.ufw:
    rule: allow
    port: '8080'
    proto: tcp
    delete: true

Application Profiles

# UFW supports application profiles
- name: Allow Nginx Full
  community.general.ufw:
    rule: allow
    name: 'Nginx Full'

Complete Firewall Playbooks

RHEL Web Server

- name: Configure RHEL firewall
  hosts: webservers
  become: true
  tasks:
    - name: Ensure firewalld is running
      ansible.builtin.service:
        name: firewalld
        state: started
        enabled: true

- name: Allow web services ansible.posix.firewalld: service: "{{ item }}" permanent: true immediate: true state: enabled loop: - http - https

- name: Allow custom app port ansible.posix.firewalld: port: 8080/tcp permanent: true immediate: true state: enabled

- name: Allow monitoring from internal ansible.posix.firewalld: rich_rule: 'rule family="ipv4" source address="10.0.0.0/24" port port="9100" protocol="tcp" accept' permanent: true immediate: true state: enabled

Ubuntu Web Server

- name: Configure Ubuntu firewall
  hosts: webservers
  become: true
  tasks:
    - name: Install UFW
      ansible.builtin.apt:
        name: ufw
        state: present

- name: Default deny incoming community.general.ufw: default: deny direction: incoming

- name: Default allow outgoing community.general.ufw: default: allow direction: outgoing

- name: Allow SSH community.general.ufw: rule: allow port: '22' proto: tcp

- name: Allow web traffic community.general.ufw: rule: allow port: "{{ item }}" proto: tcp loop: - '80' - '443'

- name: Enable UFW community.general.ufw: state: enabled

See also: Ansible Network Automation: Configure Cisco, Arista, and Juniper at Scale

firewalld vs ufw Comparison

| Feature | firewalld | ufw | |---------|-----------|-----| | Distros | RHEL, CentOS, Fedora | Ubuntu, Debian | | Zones | ✅ Yes | ❌ No | | Rich rules | ✅ Yes | Limited | | Application profiles | Limited | ✅ Yes | | Collection | ansible.posix | community.general | | Backend | nftables/iptables | iptables/nftables | | permanent + immediate | Both needed | Auto-persistent |

FAQ

Why do I need both permanent and immediate in firewalld?

permanent: true saves the rule to survive reboots. immediate: true applies it now. Without immediate, the rule only takes effect after a firewall-cmd --reload or reboot. Always use both together.

How do I reset the firewall to defaults?

For UFW: community.general.ufw: state=reset. For firewalld: remove custom rules and reload. There's no single "reset" command, but you can set the default zone back to public and remove all custom rules.

Should I use firewalld or iptables directly?

Use firewalld (or ufw) — they provide a management layer over iptables/nftables with persistent rules, zones, and easier syntax. Direct iptables rules are harder to manage and don't persist by default.

How do I check what's currently allowed?

- name: List open ports (firewalld)
  ansible.builtin.command: firewall-cmd --list-all
  register: fw_status
  changed_when: false

- name: List rules (ufw) ansible.builtin.command: ufw status verbose register: ufw_status changed_when: false

See also: Ansible on Debian 11 Bullseye: UFW Firewall Automation Complete Guide

Conclusion

Use ansible.posix.firewalld on RHEL-family systems with zones and rich rules for fine-grained control. Use community.general.ufw on Ubuntu/Debian for simpler firewall management. Always set default deny policies, open only needed ports, and use source-based restrictions for internal services.

Related Articles

Ansible service Module GuideAnsible for Linux System AdministrationAnsible Security Compliance Guide

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home