Add deliberate update playbook and unattended-upgrades role

Regular playbooks now use state: present, so they no longer upgrade
packages as a side effect. This adds two separate, explicit mechanisms
to keep the fleet patched instead:

- update-packages.yml: ad hoc / to-be-scheduled fleet-wide upgrade
  (safe by default, dist available via -e), plus
  update-packages-pinned-example.yml as a template for pinning or
  bumping a single package outside that.
- roles/unattended_upgrades: automatic security-only patching via
  unattended-upgrades, with a scheduled reboot window and mail
  left disabled pending a configured MTA. Applied to every host in
  full.yml and server.yml.

Also removes a leftover `upgrade: yes` apt task from pi_standard_setup
and server_basic_environment that was still doing a full upgrade on
every routine run, defeating the point of the state: present switch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-08 18:02:41 +02:00
parent 37b75ecf81
commit f043606466
13 changed files with 219 additions and 4 deletions

View File

@@ -12,6 +12,9 @@ Pis (audio players, sensors, music mouse, etc.) plus one home server.
runs kept around for specific hosts or one-off tasks.
- `roles/` — one role per piece of functionality (audio backends, sensors,
bluetooth monitoring, server basics, etc.). Each has a short `README.md`.
- `update-packages.yml` — deliberate, fleet-wide package update (see
"Keeping packages up to date" below). `update-packages-pinned-example.yml`
is a template for pinning or bumping a single package outside that.
- `lookup_plugins/keepass.py` — custom lookup plugin that fetches secrets
(device passwords, wifi passphrase) from a running KeePassXC instance via
its browser-integration protocol, instead of storing them in the repo.
@@ -43,3 +46,32 @@ ansible-playbook full.yml --limit <host>
`ansible.cfg` points Ansible at `inventory.yml` and `roles/` by default, so
no extra flags are needed for those.
## Keeping packages up to date
Regular playbook runs (`full.yml`, `server.yml`, etc.) use `state: present`
for packages, so they only install what's missing — they never upgrade
anything as a side effect of an unrelated config change. Two separate,
deliberate mechanisms handle upgrades instead:
**Security patches — automatic.** The `unattended_upgrades` role (applied
to every host in `full.yml`/`server.yml`) configures `unattended-upgrades`
to install security-origin updates automatically, with a scheduled reboot
window (default 03:00, see `roles/unattended_upgrades/defaults/main.yml`)
for patches that need one. Not scoped to full dist-upgrades.
**Everything else — deliberate, ad hoc.**
```
just update <host_or_group> # e.g. `just update kitchenpi` or `just update`
venv/bin/ansible-playbook update-packages.yml --limit <host> --check --diff # dry run first
```
Defaults to `upgrade: safe` (upgrades in place, never installs/removes
packages to resolve dependencies — see the comment header in
`update-packages.yml` for the tradeoff against `dist`). There is no cron/
schedule wired up for this yet; run it ad hoc when you want the fleet
updated, or add a crontab entry yourself (a starting point is documented in
`update-packages.yml`'s header).
To pin a package to an exact version, or deliberately bump one named
package to latest outside this schedule, copy the pattern in
`update-packages-pinned-example.yml`.