--- id: TECH-ARCHITECTURE type: technical status: active title: Architecture created: '2026-09-09' updated: '2026-09-09' tags: - technical - architecture - ansible related: - TECH-CODEBASE-MAP - TECH-DEPLOYMENT - TECH-INTEGRATIONS-ZABBIX - SCAN-20260909 source_paths: - ansible.cfg - execute.sh - bootstrap.yml - playbooks/ - roles/ confidence: confirmed --- # Architecture ## Overview A push-based Ansible controller-in-container setup: an interactive Docker container (built from `debian:trixie-slim`, `ansible-core 2.20.x`) runs the playbooks from the mounted repository and connects over SSH to Debian hosts (`user: admin`, `become: true`). No agent is pushed except Zabbix Agent 2. Unverified claims are marked `confidence: inferred`. ## Layered View ``` Docker runtime (execute.sh) └─ ansible-playbook -i inventory/.yml └─ SSH (admin, pipelining, no host-key checking) → Debian hosts ├─ roles/bootstrap ── composes ──► roles/docker │ └─► roles/monitoring ├─ roles/docker (Docker Engine from download.docker.com) ├─ roles/monitoring (zabbix-agent2 → repo.zabbix.com, PSK, │ Zabbix API registration via httpapi) ├─ roles/os-updates (apt full upgrade, reboot, controller logs) ├─ roles/healthcheck (container quality gate, controller logs) ├─ roles/hawser (docker_compose_v2, pull: always) └─ roles/manage-ssh-keys (authorized_keys allow/deny lists) ``` ## Role Composition - `bootstrap` is the only composing role: it imports the `docker` role and the `monitoring` role unless `skip_docker` / `skip_monitoring` are set. - `os-updates` and `healthcheck` are paired at playbook level (`playbooks/os-updates-deb.yml`); healthcheck reuses os-updates logging defaults (`healthcheck_log_file` derives from `os_update_log_dir`). ## Inventory Model - Three sites: `cloudlorean` (LAN 192.168.212.0/24, groups `debian` + `proxmox`), `home` (10.13.37.0/24, groups `debian` + `proxmox`), `external` (IPv6-only, group `debian` only). - `proxmox` group membership drives reboot deferral in `os-updates` (`'proxmox' in group_names`); `virtualization_type != lxc` skips kernel and reboot logic for LXC containers. - Per-site `group_vars/.yml` override Zabbix connectivity (server, API URL, proxy), host groups/templates; `group_vars/debian.yml` holds os-update defaults including the hardcoded `os_update_version_codename: "trixie"`. - Secrets: `vault.yml` (encrypted, tracked) provides `monitoring_zabbix_api_password` (and possibly more; vault not decrypted - `confidence: unknown`). ## Controller-Side State - `.zabbix-psk/.psk` - per-host PSKs generated once on the controller and reused across runs (keeps agent and Zabbix registration in sync). - `logs///update.log` - append-only update + quality gate log written via `delegate_to: localhost` / `blockinfile`. ## Execution Flow (os-updates-deb.yml) 1. Debian guard (fail non-Debian). 2. `os-updates`: optional mirror rewrite → preflight logging (upgradable list, start time) → `apt upgrade: full` → kernel-comparison reboot decision (async reboot + `wait_for_connection`, deferred on `proxmox` group unless `os_update_reboot_on_proxmox`) → postflight logging. 3. `healthcheck`: docker presence check → container comparison → `quality_gate` log section → optional failure (`healthcheck_fail_on_unhealthy`). ## Dependencies - Collections: `ansible.posix`, `community.general`, `community.docker`, `community.zabbix` (pinned in `docker/requirements.yml`). - External services: repo.zabbix.com, download.docker.com, Debian mirrors, Zabbix API (`mon.cloudlorean.de`). See [Integrations: Zabbix](./integrations/zabbix.md).