Files
ansible-playbooks/.project-wiki/implementation/scans/scan-20260909.md
T
DerLinkman 30f3e9a4c6 rename dmc12 inventory to cloudlorean and vault admin_password
- replace inventory/dmc12.yml with cloudlorean.yml (+ group_vars) and update
  all README/AGENTS call examples and the inventory table
- move admin_password hash into encrypted vault.yml; remove plaintext copies
  from roles/bootstrap/defaults and group_vars/external.yml
- bootstrap.yml loads vault.yml via vars_files (same pattern as monitoring)
- monitoring: PSK config/registration updates, docker role defaults,
  os-updates logging/reboot refinements, ansible.cfg/execute.sh tweaks
- add .project-wiki knowledge base and .github agent instructions
2026-09-09 14:14:18 +02:00

7.5 KiB

id, type, status, title, created, updated, tags, related, source_paths, confidence
id type status title created updated tags related source_paths confidence
SCAN-20260909 scan-report active Codebase Scan 2026-09-09 2026-09-09 2026-09-09
scan
PROJECT
TECH-CODEBASE-MAP
TECH-ARCHITECTURE
ALERT-20260909-001
ALERT-20260909-002
README.md
AGENTS.md
ansible.cfg
bootstrap.yml
execute.sh
docker/
inventory/
playbooks/
roles/
confirmed

Codebase Scan 2026-09-09

Scope

Root configuration (ansible.cfg, execute.sh), Docker runtime (docker/), all inventories and group_vars, all 6 playbooks plus bootstrap.yml, and all 7 roles (tasks/, defaults/, templates/, handlers/). Git history inspected for inventory renames. Vault-encrypted files (vault.yml) were not decrypted.

Confirmed Findings

Project Shape

  • Central Ansible collection for provisioning, hardening, updating, and monitoring Debian hosts; 7 roles, 1 top-level playbook (bootstrap.yml) and 5 playbooks under playbooks/.
  • Execution environment: Docker image ansible:deb13 built from debian:trixie-slim with ansible-core~=2.20.6; collections pinned in docker/requirements.yml (ansible.posix 2.2.0, community.general 13.0.1, community.docker 5.2.0, community.zabbix 4.2.0).
  • execute.sh creates an IPv6-enabled bridge network ansible-dualstack, starts an interactive container with the repo mounted at /ansible and an ansible_ssh_keys volume at /root/.ssh, injects SSH client config with host-key checking disabled, then attaches.
  • ansible.cfg: host_key_checking = False, roles_path = ./roles, forks = 20, gathering = smart, internal_poll_interval = 0.001, SSH pipelining and ControlPersist=60s, known hosts set to /dev/null.

Playbooks

  • All playbooks run hosts: all, user: admin, become: true, and start with a Debian os_family guard that fails non-Debian hosts.
  • Exception: playbooks/hardening/manage-ssh-keys.yml has no Debian guard, no become, and no vars_files; it binds the manage-ssh-keys role directly.
  • playbooks/monitoring.yml loads ../vault.yml via a playbook-relative path; other playbooks do not load vault.yml explicitly.
  • playbooks/os-updates-deb.yml chains os-updates then healthcheck (post-update quality gate).

Roles

  • bootstrap: subtasks for basic packages, admin user (+sudo, authorized keys), MOTD, keyboard layout, OpenSSH install/config/keys, bashrc, sysctl; then composes the docker role (skippable via skip_docker) and the monitoring role (skippable via skip_monitoring). Tags: motd, ssh, bashrc, sysctl.
  • docker: official Docker apt repository + docker-ce, CLI, containerd.io, buildx and compose plugins; template sources.list.j2; codename derived from facts.
  • os-updates: optional mirror rewrite (os_also_update_mirror, deb822 + legacy templates, codename whitelist trixie|bookworm|bullseye), full apt upgrade, kernel-comparison reboot decision with async reboot + wait_for_connection (600s timeout), reboot deferred on hosts in the proxmox group unless os_update_reboot_on_proxmox is true, LXC hosts skip kernel/reboot logic; preflight/postflight logging delegated to the controller (logs/<inventory>/<hostname>/update.log).
  • healthcheck: compares docker ps -a vs running containers, writes a quality_gate section into the same update log, fails the play when healthcheck_fail_on_unhealthy is true (default false).
  • monitoring: Zabbix 7.0 release package from repo.zabbix.com, zabbix-agent2, Docker plugin config when socket exists, per-host PSK generated on the controller (persisted in .zabbix-psk/<hostname>.psk, mode 0700, openssl rand -hex 32), deployed to /etc/zabbix/ zabbix_agent2.psk (0600), TLS connect/accept = PSK, and API host registration via community.zabbix.zabbix_host over httpapi with template union including Docker by Zabbix agent 2 when the Docker socket is present.
  • hawser: requires existing Docker host + compose file at /opt/hawser/docker-compose.yml, re-renders it from template, then docker_compose_v2 with pull: always.
  • manage-ssh-keys: ensures ~/.ssh (0700), adds good_keys, removes bad_keys from the admin user's authorized keys.

Inventories And Variables

  • inventory/cloudlorean.yml (untracked): site with groups debian (13 hosts, 192.168.212.0/24) and proxmox (dmc12 192.168.212.10, pbs 192.168.212.11); per-host ssh_service_name: ssh on gitea and ipam.
  • inventory/home.yml: site home, 6 Debian hosts + tardis (Proxmox), 10.13.37.0/24.
  • inventory/external.yml: 4 IPv6-only Debian hosts.
  • inventory/dmc12.yml is deleted in the working tree but not committed (git status: D); inventory/cloudlorean.yml and inventory/group_vars/cloudlorean.yml are untracked. Git history confirms dmc12.yml was added in d2e8ce4 and never tracked as renamed.
  • group_vars per site override Zabbix servers, API URL (https://mon.cloudlorean.de/api_jsonrpc.php), proxy (gatekeeper.cloudlorean.de / gatekeeper.meyer-kempen.de), host groups and templates. group_vars/debian.yml hardcodes os_update_version_codename: "trixie" (AGENTS.md warns about this).
  • admin_authorized_keys and the SHA-512 admin_password hash appear in plaintext in roles/bootstrap/defaults/main.yml and inventory/group_vars/external.yml (see ALERT-20260909-001).
  • vault.yml is tracked but encrypted; .vault_pass, setenv.sh, .zabbix-psk/, logs/ are git-ignored (verified via git check-ignore).

Inferred Findings

  • The environment formerly called dmc12 was renamed to cloudlorean; host dmc12 is now a Proxmox node within the cloudlorean site (confidence: inferred from logs/.zabbix-psk paths and git status).
  • Operators appear to be "Niklas" and "Dennis" (SSH key comments in bootstrap defaults). Formal ownership not documented.
  • All sites share one Zabbix server (mon.cloudlorean.de) with optional per-site proxies (confidence: inferred from group_vars).
  • Home site is referred to as "Meyer-Kempen" in Zabbix host groups/proxy name (confidence: inferred).

Unknowns

  • Whether vault.yml also defines admin_password (overriding the committed defaults hash) - vault not decrypted.
  • Whether monitoring_zabbix_passive_servers in inventory/group_vars/external.yml (2a01:4f8:1c1e:62dd::1, the healthcheck host's own address) is intentional (Zabbix server/proxy on that host) or a misconfiguration.
  • Which Docker template name exists on the Zabbix server: role default Docker by Zabbix agent2 vs group_vars Docker by Zabbix agent 2.
  • Formal stakeholders and success criteria beyond the healthcheck gate.

Important Paths

  • bootstrap.yml, playbooks/*.yml - entrypoints
  • roles/bootstrap/, roles/docker/, roles/monitoring/, roles/os-updates/, roles/healthcheck/, roles/hawser/, roles/manage-ssh-keys/ - role implementations
  • roles/*/README.md - per-role documentation (documentation duty)
  • inventory/*.yml, inventory/group_vars/*.yml - host data
  • docker/Dockerfile, docker/requirements.yml, execute.sh - runtime
  • vault.yml (encrypted), .vault_pass, setenv.sh, .zabbix-psk/, logs/ - secrets and audit artifacts (git-ignored except vault.yml)

Suggested Wiki Updates

  • Populated during this scan: technical docs (architecture, codebase map, module docs, integrations, security, deployment, testing), requirement records, open questions reconciliation, alerts ALERT-20260909-001 / ALERT-20260909-002, traceability maps, indexes, REGISTRY.yml, STATUS.md.