- Fixed 4 broken markdown links (bad relative paths in See Also sections) - Corrected n8n port binding to 127.0.0.1:5678 (matches actual deployment) - Updated SnapRAID article with actual majorhome paths (/majorRAID, disk1-3) - Converted 67 Obsidian wikilinks to relative markdown links or plain text - Added YAML frontmatter to 35 articles missing it entirely - Completed frontmatter on 8 articles with missing fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3.2 KiB
title, domain, category, tags, status, created, updated
| title | domain | category | tags | status | created | updated | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Standardizing unattended-upgrades Across Ubuntu Fleet with Ansible | selfhosting | security |
|
published | 2026-03-16 | 2026-03-16 |
Standardizing unattended-upgrades Across Ubuntu Fleet with Ansible
When some Ubuntu hosts in a fleet self-update via unattended-upgrades and others don't, they drift apart over time — different kernel versions, different reboot states, inconsistent behavior. This article covers how to diagnose the drift and enforce uniform auto-update config across all Ubuntu hosts using Ansible.
Diagnosing the Problem
If only some Ubuntu hosts are flagging for reboot, check:
# What triggered the reboot flag?
cat /var/run/reboot-required.pkgs
# Is unattended-upgrades installed and active?
systemctl status unattended-upgrades
cat /etc/apt/apt.conf.d/20auto-upgrades
# When did apt last run?
ls -lt /var/log/apt/history.log*
The reboot flag is written to /var/run/reboot-required by update-notifier-common when packages like the kernel, glibc, or systemd are updated. If some hosts have unattended-upgrades running and others don't, the ones that self-updated will flag for reboot while the others lag behind.
The Fix — Ansible Playbook
Add these tasks to your update playbook before the apt cache update step:
- name: Ensure unattended-upgrades is installed on Ubuntu servers
ansible.builtin.apt:
name:
- unattended-upgrades
- update-notifier-common
state: present
update_cache: true
when: ansible_facts['os_family'] == "Debian"
- name: Enforce uniform auto-update config on Ubuntu servers
ansible.builtin.copy:
dest: /etc/apt/apt.conf.d/20auto-upgrades
content: |
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
owner: root
group: root
mode: '0644'
when: ansible_facts['os_family'] == "Debian"
- name: Ensure unattended-upgrades service is enabled and running
ansible.builtin.systemd:
name: unattended-upgrades
enabled: true
state: started
when: ansible_facts['os_family'] == "Debian"
Running this across the ubuntu group ensures every host has the same config on every Ansible run — idempotent and safe.
Rebooting Flagged Hosts
Once identified, reboot specific hosts without touching the rest:
# Reboot just the flagging hosts
ansible-playbook reboot.yml -l teelia,tttpod
# Run full update on remaining hosts to bring them up to the same kernel
ansible-playbook update.yml -l dca,majorlinux,majortoot
Notes
unattended-upgradesruns daily on its own schedule — hosts that haven't checked yet will lag behind but catch up within 24 hours- The other hosts showing
ok(notchanged) on the config tasks means they were already correctly configured - After a kernel update is pulled, only an actual reboot clears the
/var/run/reboot-requiredflag — Ansible reporting the flag is informational only