This is a sample playbook which can be used to apply patches to a server and perform a reboot if one is required. This makes use of the handy needs-restarting
command from the yum-utils
/ dnf-utils
packages. The vars listed here are suggestions and can be updated to suit the requirements of your environment. For example, you could modify the code to specific apply certain updates from specific repos. This example playbook is used alongside Red Hat Satellite to apply O/S patches and Satellite Tools updates.
---
- name: Patch and reboot servers
hosts: all
vars:
yum_name: "*"
yum_state: latest
yum_enablerepo: "rhel-?-server-rpms,rhel-?-server-satellite-tools-6.?-rpms"
yum_disablerepo: "*"
yum_exclude: ""
dnf_name: "*"
dnf_state: latest
dnf_enablerepo: "rhel-8-for-x86_64-appstream-rpms,rhel-8-for-x86_64-baseos-rpms,satellite-tools-6.?-for-rhel-8-x86_64-rpms"
dnf_disablerepo: "*"
dnf_exclude: ""
tasks:
- name: upgrade packages via yum
yum:
name={{ yum_name }}
state={{ yum_state }}
disablerepo={{ yum_disablerepo }}
enablerepo={{ yum_enablerepo }}
exclude={{ yum_exclude }}
become: "yes"
register: yumcommandout
when:
- (ansible_facts['distribution_major_version'] == '6') or
(ansible_facts['distribution_major_version'] == '7')
- name: Print errors if yum failed
debug:
msg: "yum command produced errors"
when: yumcommandout is not defined
- name: upgrade packages via dnf
dnf:
name={{ dnf_name }}
state={{ dnf_state }}
disablerepo={{ dnf_disablerepo }}
enablerepo={{ dnf_enablerepo }}
exclude={{ dnf_exclude }}
become: "yes"
register: dnfcommandout
when:
- ansible_facts['distribution_major_version'] == '8'
- name: Print errors if dnf failed
debug:
msg: "dnf command produced errors"
when: dnfcommandout is not defined
- name: check to see if we need a reboot
command: needs-restarting -r
register: result
ignore_errors: yes
- name: display result
debug:
var: result.rc
- name: Reboot Server if Necessary
command: shutdown -r now "Ansible Updates Triggered"
become: true
async: 30
poll: 0
when: result.rc == 1
# This pause is mandatory, otherwise the existing control connection
# gets reused!
# (https://gist.github.com/infernix/a968f23c4f4e1d6723e4)
- name: Pausing to allow server to shutdown and terminate our SSH connection
pause: seconds=30
when: result.rc == 1
- name: Wait for reboot to complete and SSH to become available
local_action: wait_for host={{ inventory_hostname }} port=22
state=started delay=30 timeout=600
retries: 30
delay: 10
when: result.rc == 1