# ansible Personal Ansible setup for provisioning and maintaining a fleet of Raspberry Pis (audio players, sensors, music mouse, etc.) plus one home server. ## Layout - `inventory.yml` — hosts and group vars (Pis under `iot`, plus `server`). `group_vars/` and `host_vars/` hold vars for the `mediapis` group (the four parallel audio-player Pis) and their host-specific overrides. - `mediapis.yml`, `working.yml`, `server.yml`, `newrpi-provisioning.yml`, `octopisetup.yml` — top-level playbooks. `mediapis.yml` is the canonical playbook for the `mediapis` group (`musicdolphin`, `kitchenpi`, `bedroompi`, `musicmouse`); the others are narrower/ad-hoc 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. - `pis/` — loose config files/scripts used when provisioning Pis by hand. - `scripts/` — standalone helper scripts (Raspbian image creation, a network logger) that aren't Ansible roles. - `archive/` — retired setups kept for reference (not actively maintained). ## Setup ``` python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` Secrets are pulled from KeePassXC at run time via the `keepass` lookup plugin — see the header of `lookup_plugins/keepass.py` for how to enable Browser Integration in KeePassXC. Freshly-flashed Raspberry Pis are reached first with the OS-default `pi`/`raspberry` credentials (see `roles/pi_standard_setup`), which the role then rotates to a KeePassXC-managed password. ## Running a playbook ``` ansible-playbook mediapis.yml --limit ``` `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 (`mediapis.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 `mediapis.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 # e.g. `just update kitchenpi` or `just update` venv/bin/ansible-playbook update-packages.yml --limit --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`.