--- - name: Apply security updates hosts: wulf_security become: true serial: "{{ serial | default('100%') }}" vars: apprise_url: "https://apprise.wulfconsulting.cloud" tasks: - name: Update apt cache ansible.builtin.apt: update_cache: yes cache_valid_time: 0 - name: Ensure unattended-upgrades is installed ansible.builtin.apt: name: unattended-upgrades state: present - name: Apply security updates ansible.builtin.command: cmd: unattended-upgrade --verbose register: upgrade_result changed_when: "'Packages that will be upgraded' in upgrade_result.stdout" - name: Check if reboot is required ansible.builtin.stat: path: /var/run/reboot-required register: reboot_required_file - name: Flag hosts requiring reboot ansible.builtin.debug: msg: "REBOOT REQUIRED: {{ inventory_hostname }} must be rebooted to complete updates" when: reboot_required_file.stat.exists - name: Record reboot status ansible.builtin.set_fact: reboot_needed: "{{ reboot_required_file.stat.exists }}" - name: Send Apprise notification hosts: localhost gather_facts: false vars: apprise_url: "https://apprise.wulfconsulting.cloud" tasks: - name: Build list of hosts requiring reboot ansible.builtin.set_fact: hosts_needing_reboot: >- {{ groups['wulf_security'] | select('in', hostvars) | selectattr('reboot_needed', 'defined') | selectattr('reboot_needed') | list }} - name: Send completion notification ansible.builtin.uri: url: "{{ apprise_url }}/notify" method: POST body_format: json status_code: [200, 204] body: title: "Security Updates Complete" body: >- Security updates applied to {{ groups['wulf_security'] | length }} host(s) in the wulf_security group. {%- if hosts_needing_reboot | length > 0 %} Reboot required on: {{ hosts_needing_reboot | join(', ') }} {%- else %} No reboots required. {%- endif %} type: "{% if hosts_needing_reboot | length > 0 %}warning{% else %}success{% endif %}"