151 lines
5.7 KiB
YAML
151 lines
5.7 KiB
YAML
---
|
|
- name: Patch Test Rocky servers and report to generic webhook
|
|
hosts: rocky_servers
|
|
become: true
|
|
gather_facts: true
|
|
|
|
vars:
|
|
discord_webhook_id: "1396804024942198794"
|
|
discord_webhook_token: "zdT2wisqhAZuZ_UPKmAmtV0z_rX-PZnyHIXsjpPHQO3uakBO2xQ3R44kOxb9QZ4QxebL"
|
|
|
|
tasks:
|
|
- name: Verify target is RedHat family
|
|
ansible.builtin.assert:
|
|
that:
|
|
- ansible_os_family == "RedHat"
|
|
fail_msg: "This playbook is intended for Rocky/RHEL-family systems only."
|
|
success_msg: "Target is RedHat family."
|
|
|
|
- name: Refresh DNF metadata
|
|
ansible.builtin.raw: |
|
|
dnf -y makecache
|
|
register: dnf_cache_result
|
|
changed_when: false
|
|
failed_when: dnf_cache_result.rc != 0
|
|
become: true
|
|
|
|
- name: Check for available updates
|
|
ansible.builtin.raw: |
|
|
dnf check-update
|
|
register: dnf_check_update_result
|
|
changed_when: false
|
|
failed_when: dnf_check_update_result.rc not in [0, 100]
|
|
become: true
|
|
|
|
- name: Upgrade packages
|
|
ansible.builtin.raw: |
|
|
dnf -y upgrade
|
|
register: dnf_upgrade_result
|
|
changed_when: dnf_check_update_result.rc == 100
|
|
failed_when: dnf_upgrade_result.rc != 0
|
|
become: true
|
|
when: dnf_check_update_result.rc == 100
|
|
|
|
- name: Mark package upgrade unchanged when no updates exist
|
|
ansible.builtin.set_fact:
|
|
dnf_upgrade_result:
|
|
changed: false
|
|
rc: 0
|
|
stdout: "No package updates available"
|
|
when: dnf_check_update_result.rc == 0
|
|
|
|
- name: Autoremove unused packages
|
|
ansible.builtin.raw: |
|
|
dnf -y autoremove
|
|
register: dnf_autoremove_result
|
|
changed_when: >
|
|
'Removed:' in dnf_autoremove_result.stdout or
|
|
'Removing' in dnf_autoremove_result.stdout
|
|
failed_when: dnf_autoremove_result.rc != 0
|
|
become: true
|
|
|
|
- name: Check if reboot is required
|
|
ansible.builtin.command:
|
|
cmd: needs-restarting -r
|
|
register: reboot_required_check
|
|
changed_when: false
|
|
failed_when: reboot_required_check.rc not in [0, 1]
|
|
|
|
- name: Set reboot required fact
|
|
ansible.builtin.set_fact:
|
|
reboot_required: "{{ reboot_required_check.rc == 1 }}"
|
|
|
|
- name: Reboot server if required
|
|
ansible.builtin.reboot:
|
|
pre_reboot_delay: 60
|
|
post_reboot_delay: 60
|
|
reboot_timeout: 600
|
|
msg: "Rebooting in 60 seconds, initiated by Ansible"
|
|
when: reboot_required
|
|
register: reboot_result
|
|
|
|
- name: Build per-host summary
|
|
ansible.builtin.set_fact:
|
|
patch_summary: |
|
|
Host: {{ inventory_hostname }}
|
|
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
|
|
DNF Utils Changed: {{ 'Yes' if (dnf_utils_result.changed | default(false)) else 'No' }}
|
|
DNF Cache Updated: {{ 'Yes' if (dnf_cache_result.changed | default(false)) else 'No' }}
|
|
Packages Upgraded: {{ 'Yes' if (dnf_upgrade_result.changed | default(false)) else 'No' }}
|
|
Autoremove Changed: {{ 'Yes' if (dnf_autoremove_result.changed | default(false)) else 'No' }}
|
|
Reboot Required: {{ 'Yes' if (reboot_required | default(false)) else 'No' }}
|
|
Reboot Performed: {{ 'Yes' if (reboot_result.changed | default(false)) else 'No' }}
|
|
|
|
Reboot Check Output:
|
|
{{ reboot_required_check.stdout | default('') | indent(10, true) }}
|
|
|
|
- name: Build per-host summary
|
|
ansible.builtin.set_fact:
|
|
patch_summary: |
|
|
Host: {{ inventory_hostname }}
|
|
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
|
|
DNF Utils Changed: {{ 'Yes' if (dnf_utils_result.changed | default(false)) else 'No' }}
|
|
DNF Cache Updated: {{ 'Yes' if (dnf_cache_result.changed | default(false)) else 'No' }}
|
|
Packages Upgraded: {{ 'Yes' if (dnf_upgrade_result.changed | default(false)) else 'No' }}
|
|
Autoremove Changed: {{ 'Yes' if (dnf_autoremove_result.changed | default(false)) else 'No' }}
|
|
Reboot Required: {{ 'Yes' if (reboot_required | default(false)) else 'No' }}
|
|
Reboot Performed: {{ 'Yes' if (reboot_result.changed | default(false)) else 'No' }}
|
|
|
|
Reboot Check Output:
|
|
{{ reboot_required_check.stdout | default('') | indent(10, true) }}
|
|
|
|
- name: Send Discord Rocky update report
|
|
community.general.discord:
|
|
webhook_id: "{{ discord_webhook_id }}"
|
|
webhook_token: "{{ discord_webhook_token }}"
|
|
username: "Ansible"
|
|
content: |
|
|
======================================
|
|
Rocky Servers Update Report
|
|
Generated: {{ lookup('pipe', 'date +%Y-%m-%dT%H:%M:%SZ') }}
|
|
======================================
|
|
|
|
Total Hosts: {{ ansible_play_hosts_all | length }}
|
|
|
|
{% for host in ansible_play_hosts_all | sort %}
|
|
{{ hostvars[host].patch_summary | default('Host: ' ~ host ~ '\n No summary generated\n') }}
|
|
|
|
{% endfor %}
|
|
======================================
|
|
Summary
|
|
======================================
|
|
Hosts Requiring Reboot: {{
|
|
ansible_play_hosts_all
|
|
| map('extract', hostvars)
|
|
| selectattr('reboot_required', 'defined')
|
|
| selectattr('reboot_required')
|
|
| list
|
|
| length
|
|
}}
|
|
|
|
Hosts Rebooted: {{
|
|
ansible_play_hosts_all
|
|
| map('extract', hostvars)
|
|
| selectattr('reboot_result.changed', 'defined')
|
|
| selectattr('reboot_result.changed')
|
|
| list
|
|
| length
|
|
}}
|
|
delegate_to: localhost
|
|
run_once: true
|
|
become: false |