Read references/configuration.md before changing desired state or running a real lifecycle operation.
The package creates three ClickHouse/Keeper nodes and one Metabase/Postgres server. Cloudflare names resolve to WireGuard addresses. ClickHouse and Metabase service ports are never public. Local dbt seeds and tests a replicated sample model, registers ClickHouse in Metabase, runs end-to-end acceptance checks, and proves every OpenTofu state has no remaining drift.
Safety
- Keep secrets only in gitignored
.envrc.privateasCOLORS_PAR_*exports. - Never set
COLORS_PAR_PROFILE. - Never edit or commit
.colors/. - Keep
compute-prevent-destroy: true; override it for one authorized delete. - Run
buildandcreate --dry-runbefore a real lifecycle operation. - The library owns generated SSH keys at
~/.ssh/<profile>. WireGuard keys remain on the hosts. Never commit either private key.
Commands
./green build
./green create --dry-run
./green create
./green delete
After create, browse http://metabase.<domain>:3000 and run dbt from
.colors/<profile>/clickhouse-dbt/ through uv run dbt .... Both require the
managed WireGuard interface.
Metabase from a computer outside WireGuard
Use an SSH local port forward through a host that is connected to this deployment's WireGuard network and can resolve its private DNS:
ssh -N \
-o ExitOnForwardFailure=yes \
-L 3000:metabase.<domain>:3000 \
ubuntu@<WIREGUARD_JUMPHOST>
Keep that command running and open http://localhost:3000 in the browser. The
jump host, rather than the computer running the browser, resolves
metabase.<domain> and opens the private WireGuard connection.
If local port 3000 is already occupied, choose another local port while keeping the remote port unchanged:
ssh -N \
-o ExitOnForwardFailure=yes \
-L 3300:metabase.<domain>:3000 \
ubuntu@<WIREGUARD_JUMPHOST>
Then open http://localhost:3300. Do not publish Metabase or weaken the
firewall as an alternative to this tunnel.
Shared compute library
The package uses colors-compute for its three ClickHouse nodes and one Metabase
node. The library owns provider validation, R2 or S3 state, shared networking,
SSH keys, node fan-out, and the complete inventory used by Ansible. Select
provider-compute and supply the selected provider's settings. Compatible
provider additions require a library dependency update only.
Generated SSH keys live at ~/.ssh/<profile>. External SSH access uses the provider's public-key or registration settings.
ssh-private-key-path is optional; when omitted, SSH uses the operator's
configuration or agent.
The package keeps the WireGuard addresses and DNS records stable. Ansible uses
the actual node login user and private network address returned by the library.
Existing deployments with the former package-owned compute state require an explicit state migration. The lifecycle refuses that state before creating resources. Updating a launcher does not transfer state ownership.