Files
MajorWiki/02-selfhosting/security/ansible-unattended-upgrades-fleet.md
MajorLinux 6592eb4fea wiki: audit fixes — broken links, wikilinks, frontmatter, stale content (66 files)
- 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>
2026-04-02 11:16:29 -04:00

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
ansible
ubuntu
apt
unattended-upgrades
fleet-management
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-upgrades runs 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 (not changed) 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-required flag — Ansible reporting the flag is informational only

See Also