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.
- 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:
- 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.