Skip to content

Detect if a Reboot is required#

Problem#

After installing package updates, some of them — a new kernel, systemd or a core library — only take effect after a restart. We do not want to reboot every host on every run, but only those that actually ask for it.

Solution#

On Debian and Ubuntu, the package tooling creates the file /var/run/reboot-required whenever an installed package needs a restart. We check for that file and make the reboot conditional on it.

reboot-required.yaml
- name: Check if a reboot is required on Debian 13
  ansible.builtin.stat:
    path: /var/run/reboot-required
  register: reboot_required_file

- name: Reboot the server if needed
  ansible.builtin.reboot:
    msg: "Rebooting machine due to system updates requiring a restart."
    connect_timeout: 5
    reboot_timeout: 600
  when: reboot_required_file.stat.exists

On the Red Hat family there is no such marker file. Instead, dnf needs-restarting -r exits with return code 1 when a reboot is pending:

reboot-required.yaml
- name: Check if a reboot is required on Red Hat
  ansible.builtin.command: dnf needs-restarting -r
  register: needs_restarting
  changed_when: false
  failed_when: false
  check_mode: false

- name: Reboot the server if needed
  ansible.builtin.reboot:
    msg: "Rebooting machine due to system updates requiring a restart."
    connect_timeout: 5
    reboot_timeout: 600
  when: needs_restarting.rc == 1

Explanation#

The ansible.builtin.stat module does not change anything on the host, it only reports what it finds at the given path. We store its result in reboot_required_file so the rest of the play can use it:

- name: Check if a reboot is required on Debian 13
  ansible.builtin.stat:
    path: /var/run/reboot-required
  register: reboot_required_file

The interesting part is stat.exists, a boolean that is false instead of undefined when the file is absent. That makes it safe to use directly in a condition, without a default() filter:

- name: Reboot the server if needed
  ansible.builtin.reboot:
    msg: "Rebooting machine due to system updates requiring a restart."
    connect_timeout: 5
    reboot_timeout: 600
  when: reboot_required_file.stat.exists

The ansible.builtin.reboot module does more than send reboot to the host: it disconnects, waits for the machine to come back and only then reports success. connect_timeout is how long a single connection attempt may take, while reboot_timeout is the total budget for the host to become reachable again. Hosts with slow firmware or many services to stop deserve a generous reboot_timeout.

In the Red Hat variant we call an external command, so we have to tell Ansible how to interpret it. changed_when: false keeps a pure query from being reported as a change, failed_when: false stops the return code 1 from aborting the play, and check_mode: false makes the check run even during a --check run, so that the condition is evaluated there as well.

Note that the check only makes sense after the updates have been applied. If the package updates happen in the same play, put the check after them — the marker file is written by the package manager during installation.

See also#