Execute a required reboot, with Ansible (CentOS/Red Hat)

Posted by ads' corner on Tuesday, 2016-08-23
Posted in [Ansible][Linux]

A while ago I blogged about executing a reboot using Ansible on Debian-based operating systems. That is necessary after certain updates, as example after installing a new kernel. Turns out that things are very easy on Debian, compared to Red Hat based systems (Red Hat and CentOS in my case).

First of all, there is no clear indicator if a reboot is required. People work around this problem by creating overly complicated scripts. The needs-restarting tool in newer versions provides the -r option to indicate if a reboot is required. But the CentOS 7 I’ve just installed does not come with this version.

I have no patience for complicated solutions when things could be easy. Red Hat is 16 years on the market, and the need for occasionally reboots is even older than that. After such a long time they could have figured out a good way to indicate a required reboot. Therefore my Ansible playbook installs the updated version of needs-restarting in /root.

1
2
3
- name: install own version of 'needs-restarting'
  copy: src=needs-restarting.py dest=/root/needs-restarting.py mode=0700
  when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux'

The step to identify if a reboot is required is split in two parts: 1) run needs-restarting -r and save the result and 2) execute the reboot based on the return code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
- name: Reboot required (Red Hat) - Step 1
  command: /root/needs-restarting.py -r
  register: reboot_required
  ignore_errors: True
  changed_when: False
  when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux'

- name: Reboot required (Red Hat) - Step 2
  shell: ( /bin/sleep 5 ; shutdown -r now "Ansible updates triggered" ) &
  async: 30
  poll: 0
  ignore_errors: true
  notify:
    - waiting for server to come back after reboot
  when: (ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux') and reboot_required.rc == 1

The reboot_required variable stores the result of the command, and the return code is used in the second task. A return code == 1 indicates that a restart is required.

The handler to wait for the server to come back online is the same as I’m using with Debian:

1
2
3
- name: waiting for server to come back after reboot
  local_action: wait_for host={{ inventory_hostname }} port=22 state=started delay=10 timeout=60
  become: no

Categories: [Ansible] [Linux]