--- - name: Apply operating-system, SSH, Fail2ban, and UFW hardening hosts: debian_servers become: true gather_facts: true serial: 1 pre_tasks: - name: Require a supported Debian or Ubuntu system ansible.builtin.assert: that: - ansible_distribution in ["Debian", "Ubuntu"] - ansible_service_mgr == "systemd" fail_msg: >- This playbook targets Debian or Ubuntu hosts using systemd. Review the inventory and platform facts before applying it elsewhere. - name: Confirm UFW is configured to preserve the current SSH path ansible.builtin.assert: that: - ansible_port | default(22) | int == ssh_port | int or (ssh_keep_legacy_port | bool and ansible_port | default(22) | int == ssh_legacy_port | int) fail_msg: >- Keep the current Ansible connection port in sshd and UFW during the first run. After confirming the new port works, update ansible_port and rerun with ssh_keep_legacy_port=false. roles: - role: baseline tags: [baseline] - role: hardening tags: [hardening, ssh, fail2ban, ufw] handlers: - name: Restart active SSH socket after reloading systemd ansible.builtin.systemd_service: name: ssh.socket daemon_reload: true state: restarted listen: Apply SSH changes when: hardening_ssh_socket.rc == 0 - name: Reload ssh ansible.builtin.service: name: ssh state: reloaded listen: Apply SSH changes when: hardening_ssh_socket.rc != 0 or hardening_ssh_service.rc == 0 - name: Restart fail2ban ansible.builtin.service: name: fail2ban state: restarted