From 305f1f6245402af91df0455f82c84f9cce0a3f80 Mon Sep 17 00:00:00 2001 From: Nik Date: Wed, 15 Jul 2026 12:49:25 -0600 Subject: [PATCH] =?UTF-8?q?docs(infra):=20automation=20stack=20=E2=80=94?= =?UTF-8?q?=20tools=20&=20layers=20canon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the canonical tool-per-layer assignment (OpenTofu=provision incl. DNS/CF as it lands in IaC, Ansible=configure, Wrangler=CF artifact deploy via committed scripts, Infisical=cross-cutting secrets) plus two corollaries: second-occurrence curl mutations go to tofu, and secrets are consumed in-process via a logged-in CLI (command substitution), never copy-pasted from a store UI. --- docs/INFRA_BOOTSTRAP_PATTERN.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/INFRA_BOOTSTRAP_PATTERN.md b/docs/INFRA_BOOTSTRAP_PATTERN.md index 2fd337ca..23f4eec5 100644 --- a/docs/INFRA_BOOTSTRAP_PATTERN.md +++ b/docs/INFRA_BOOTSTRAP_PATTERN.md @@ -459,6 +459,34 @@ deployment scale. --- +## Automation stack — tools & layers + +The canonical tool-per-layer assignment for WeOwn infrastructure. Use the tool +that owns the layer; don't reach across (e.g. no ad-hoc `curl` mutations of DNS +that OpenTofu could own, no ansible provisioning of cloud resources). + +| Tool | Layer | Owns | +|---|---|---| +| **OpenTofu** (`itofu.sh`) | **Provision** | *All* cloud resources: DO droplets, reserved IPs, firewalls, monitor alerts — and, as it lands in IaC, DNS records and Cloudflare Pages projects/custom domains (both DO and Cloudflare have first-class providers). | +| **Ansible** (`deploy.yml`) | **Configure** | Everything on the host after bootstrap: compose files, Caddyfile, backup cron, SSH key sync, log dirs. Idempotent; the change-control surface (Path C). | +| **Wrangler** | **Deploy (Cloudflare surfaces)** | Pushing built artifacts to CF Pages/Workers — the CF-runtime analog of `docker compose up`. Always invoked via a committed `package.json` script (`npm run deploy`), never ad-hoc flags. | +| **Infisical** | **Secrets (cross-cutting)** | Feeds all of the above: `TF_VAR_*` via `itofu.sh`, app secrets via `infisical run` at container start, `CLOUDFLARE_API_TOKEN` for wrangler. No secret lives anywhere else. | + +Two corollaries: + +1. **One-off `curl` mutations of cloud state are break-glass, not practice.** + The first occurrence is tolerable; the second means the resource belongs in + OpenTofu (e.g. a `digitalocean_record` + `cloudflare_pages_domain` module for + embed sites). +2. **Consume secrets in-process, never by copy-paste.** Under a logged-in + `infisical` CLI, scripts and hand-off blocks read values via command + substitution — `VAR="$(infisical secrets get KEY --projectId= --env=prod --plain)"` — + so values never hit a terminal, clipboard, shell history, or an AI agent's + context. Sending an operator to the Infisical UI to copy a value that a + logged-in CLI could fetch is an anti-pattern. + +--- + ## Compliance mapping | Control | Addressed by |