Skip to content

Provisioning build order — ADRs to Ansible roles

Do NOT write provisioning logic solo. The decisions are made; these notes say which role owns which decision and the safe order to build and run them.

Baseline: ADR-0021 (host), ADR-0022 (edge/TLS/hostnames), ADR-0023 (container isolation), ADR-0024 (Ansible layout), ADR-0025 (control-plane co-location), ADR-0026 (backups), ADR-0027 (secrets and credential custody). (These superseded ADR-0014, which bundled all of them into one document.)

Role ownership

Role Owns ADR
common Base packages, timezone, unattended OS upgrades ADR-0021
hardening SSH (keys, no root, per-person users, non-standard port), fail2ban, firewall (deny + SSH/80/443) ADR-0021
docker Docker + Compose, network model (per-tenant + shared-core nets), restart policy, resource limits, pinned image versions ADR-0023
caddy Caddy install, wildcard TLS via Cloudflare DNS challenge, hostname routing, /insights and /health subpaths ADR-0022
core_stack LangGraph, registry (Postgres, own network, tenants reach it only via the API), monitoring ADR-0025
tenant_stack One tenant: business Postgres (pgvector, pinned, RLS-ready), a dedicated n8n instance (Projects not used), n8n's own Postgres, private network ADR-0023
metabase Conditional — only for tenants whose services list includes it. Pinned version + scheduled bump ADR-0023
dns Tenant DNS record creation via zone-scoped Cloudflare token. Deletion is never automated ADR-0022, ADR-0024
backup Tiered by recoverability, per-tenant dumps to per-tenant paths, AU object storage, encrypted ADR-0026
(secrets) Ansible Vault, per-tenant --vault-id, inline encrypt_string, no key material on the host ADR-0027

Safe build/run order

  1. hardening — lock the box down first. Two-phase; VERIFY both admins' keys on the new port before closing 22.
  2. docker — runtime and networks.
  3. caddy — front door and TLS. Needs DNS plus the scoped Cloudflare token. Milestone: https://console.octopodia.com.au serves a placeholder. That single page proves DNS, firewall, Caddy, the token and TLS all work.
  4. core_stack — brain, registry, monitoring.
  5. tenant_stack — stand up client-zero as tenant zero.
  6. backup — before any real data matters. The restore test is the deliverable, not the dump.
  7. (secrets) — threaded through all of the above. Vault from the start, never bolted on.

Steps 4–5 are blocked. There is no brain or registry image to deploy yet. Steps 1–3 are buildable and testable today; stop at the milestone in step 3.

Client-zero — tenant zero, not client one

One tenant: Octopodia's own inbox. Email triage only. Assist autonomy (approve every draft). Prove the full stack on ourselves for roughly a month before the first paying client.

Greenhills is the first client tenant, not tenant one. We do not learn tenant provisioning on a paying client. ADR-0025's "shared by default" applies to both; the ordering is client-zero first.

Deferred — hooks exist, logic later

Tailscale (close the public SSH port, ADR-0021 §6) · block-storage migration · RLS enforcement (ADR-0017) · tenant mode/expiry logic (ADR-0013) · reconciliation pass (ADR-0006) · control-plane split (ADR-0025 §3).