--- - name: Update apt cache ansible.builtin.apt: update_cache: true cache_valid_time: 3600 - name: Upgrade all packages ansible.builtin.apt: upgrade: safe - name: Install common packages ansible.builtin.apt: name: "{{ common_packages }}" state: present - name: Create deploy user ansible.builtin.user: name: "{{ deploy_user }}" shell: /bin/bash groups: sudo append: true create_home: true state: present - name: Set authorized key for deploy user ansible.posix.authorized_key: user: "{{ deploy_user }}" key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}" state: present - name: Allow deploy user passwordless sudo ansible.builtin.copy: content: "{{ deploy_user }} ALL=(ALL) NOPASSWD:ALL\n" dest: "/etc/sudoers.d/{{ deploy_user }}" mode: "0440" validate: "visudo -cf %s" - name: Deploy hardened sshd_config ansible.builtin.template: src: sshd_config.j2 dest: /etc/ssh/sshd_config owner: root group: root mode: "0600" validate: "sshd -t -f %s" notify: Restart sshd - name: Configure UFW defaults - deny incoming community.general.ufw: direction: incoming policy: deny - name: Configure UFW defaults - allow outgoing community.general.ufw: direction: outgoing policy: allow - name: Allow SSH on custom port community.general.ufw: rule: allow port: "{{ ssh_port }}" proto: tcp comment: "SSH custom port" - name: Enable UFW community.general.ufw: state: enabled - name: Enable and start chrony ansible.builtin.systemd: name: chrony enabled: true state: started - name: Configure unattended-upgrades — origins ansible.builtin.copy: content: | // Automatically install security updates and stable updates Unattended-Upgrade::Origins-Pattern { "origin=Debian,codename=${distro_codename},label=Debian"; "origin=Debian,codename=${distro_codename},label=Debian-Security"; "origin=Debian,codename=${distro_codename}-security,label=Debian-Security"; "origin=Debian,codename=${distro_codename}-updates,label=Debian"; }; // Auto-remove unused kernel packages and dependencies Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; Unattended-Upgrade::Remove-New-Unused-Dependencies "true"; Unattended-Upgrade::Remove-Unused-Dependencies "true"; // Reboot at 4 AM if a kernel update requires it Unattended-Upgrade::Automatic-Reboot "true"; Unattended-Upgrade::Automatic-Reboot-Time "04:00"; // Email notification (optional — only if mail is configured) // Unattended-Upgrade::Mail "root"; // Log to syslog Unattended-Upgrade::SyslogEnable "true"; dest: /etc/apt/apt.conf.d/50unattended-upgrades owner: root group: root mode: "0644" - name: Configure auto-update schedule ansible.builtin.copy: content: | // Run apt update and unattended-upgrade daily APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1"; APT::Periodic::Download-Upgradeable-Packages "1"; APT::Periodic::AutocleanInterval "7"; dest: /etc/apt/apt.conf.d/20auto-upgrades owner: root group: root mode: "0644" - name: Enable and start unattended-upgrades ansible.builtin.systemd: name: unattended-upgrades enabled: true state: started