--- - name: Install nftables ansible.builtin.apt: name: nftables state: present tags: [firewall] - name: Ensure nftables drop-in dir exists ansible.builtin.file: path: "{{ base__firewall_dropin_dir }}" state: directory mode: "0755" tags: [firewall] - name: Resolve firewall ingress rules for this host ansible.builtin.set_fact: base__firewall_resolved: >- {{ firewall_catalog | default({}) | resolve_firewall_rules(firewall_zones | default({}), inventory_hostname, hostvars, groups) }} tags: [firewall] - name: Render nftables ruleset (syntax-checked before install) ansible.builtin.template: src: nftables.conf.j2 dest: /etc/nftables.conf mode: "0644" validate: "nft -c -f %s" register: base__firewall_render tags: [firewall] - name: Apply firewall ruleset safely (with auto-rollback) when: - base__firewall_apply | bool - base__firewall_render is changed tags: [firewall] block: - name: Snapshot the current ruleset as the rollback point ansible.builtin.shell: "nft list ruleset > /etc/nftables.rollback" changed_when: false - name: Stop stale rollback timer unit ansible.builtin.systemd: name: "{{ item }}" state: stopped loop: - nft-rollback.timer - nft-rollback.service failed_when: false changed_when: false - name: Reset failed state on stale rollback units ansible.builtin.command: systemctl reset-failed {{ item }} loop: - nft-rollback.timer - nft-rollback.service failed_when: false changed_when: false - name: Arm the auto-rollback timer ansible.builtin.command: cmd: >- systemd-run --on-active={{ base__firewall_rollback_timeout }} --unit=nft-rollback /usr/sbin/nft -f /etc/nftables.rollback changed_when: true - name: Apply the new ruleset ansible.builtin.command: nft -f /etc/nftables.conf changed_when: true - name: Stop the rollback timer after connectivity confirmed ansible.builtin.systemd: name: "{{ item }}" state: stopped loop: - nft-rollback.timer - nft-rollback.service failed_when: false changed_when: false - name: Reset failed state on rollback units after disarm ansible.builtin.command: systemctl reset-failed {{ item }} loop: - nft-rollback.timer - nft-rollback.service failed_when: false changed_when: false - name: Enable nftables.service so the ruleset persists across reboot ansible.builtin.systemd: name: nftables enabled: true when: base__firewall_apply | bool tags: [firewall]