- 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
164 lines
7.5 KiB
Markdown
164 lines
7.5 KiB
Markdown
---
|
|
id: SCAN-20260909
|
|
type: scan-report
|
|
status: active
|
|
title: Codebase Scan 2026-09-09
|
|
created: 2026-09-09
|
|
updated: 2026-09-09
|
|
tags: [scan]
|
|
related: [PROJECT, TECH-CODEBASE-MAP, TECH-ARCHITECTURE, ALERT-20260909-001, ALERT-20260909-002]
|
|
source_paths:
|
|
- README.md
|
|
- AGENTS.md
|
|
- ansible.cfg
|
|
- bootstrap.yml
|
|
- execute.sh
|
|
- docker/
|
|
- inventory/
|
|
- playbooks/
|
|
- roles/
|
|
confidence: 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.
|