3.8 KiB
3.8 KiB
Session 2026-06-30 #001 — Foundation bootstrap: contracts → live VM + DNS + offsite backup
What was done
- T00 contracts CONTRACT_001–004 (+ amendment for
hosts.git,vm.sshPort,cloudflare.zoneId). - T01
preflight/+VERSIONS(images carry:PIN_DIGESTplaceholders — see gotchas). - T02 Bun-workspace + typed
config.ts+ vendored@olsitec/pulumi-{docker,vault}. - ADR-006 precursor: shared Docker-over-SSH provider +
foundation-net(lib/context.ts,components/network.ts, phase-slottedindex.ts). Composition = per-component factories, gates viadependsOn. - Phase-0 VM: vendored
@olsitec/pulumi-hetzner;provision/stack. Live: cx33 Helsinki,204.168.234.72, Docker 29.6.1, SSH port 222, key~/.ssh/foundation-test_ed25519, firewall 222/80/443/2222. - Offsite backup:
offsite-backup/stack — bucketolsitec-foundation+ scoped service account onminio.wob.olsitec.de:19000(home Synology). Verified scoped (cross-bucket denied). - Steps 1+2: real
olsitec.netconfig + DNSforge/vault/s3/git.olsitec.net → 204.168.234.72(verified authoritative; explicit A shadows the*.olsitec.netwildcard).foundation-netlive on VM.
Current state
- Repo:
~/work/olsitec-foundation/foundation. Latest commit185be52. Working tree clean. - Master passphrase (the one external secret):
pass olsitec-foundation/PULUMI_CONFIG_PASSPHRASE. - Deploy the foundation:
cd bootstrap && ./run.sh up(sets passphrase +SSH_PRIVATE_KEY_PATH). - Stacks (all local file backends):
bootstrapstack foundation (real passphrase);provisionstack foundation-test +offsite-backupstack prod (throwaway passphrasedev-validation-throwaway). - Other creds:
pass olsicloud4/{HCLOUD_TOKEN,CLOUDFLARE_MASTER_TOKEN}; MinIO admin via thewob-admin-externalmc alias (accessKeyadmin, NOTpass MINIO_BACKUP_*which is a different instance).
Next steps (Wave 2 → the goal: git clone git@git.olsitec.net)
Validate each live on the VM via bootstrap/run.sh up (images still unpinned → FOUNDATION_ALLOW_UNPINNED=1
or pin digests per VERSIONS header). Each component is a factory components/<svc>.ts, wired into the
index.ts phase slots (ADR-006).
- T03 postgres · T04 rustfs (+ buckets) — data plane.
- T05 vault — sealed container + init-capture (reuse
olsitec-core/run.shpattern → unseal keys tovaultCredentials:*encrypted config) + passphrase-gated unseal helper (ADR-004). The hard one. - T06 credentials —
@pulumi/random→ Vault (CONTRACT_002 paths). - T07 Caddy — DNS-01 TLS; needs a Cloudflare-enabled Caddy image (build via xcaddy; standard
caddy:2lacks the DNS plugin). Token already infoundation:cloudflareApiToken. - T08 Forgejo — app.ini ← Postgres/RustFS/Vault; first admin headless; org + repo so
git clone git@git.olsitec.net:olsitec/...works (forgeSshPort 2222, published). - T10 runner · T12 backup (RustFS → replicate to the offsite
olsitec-foundationbucket; scoped creds already infoundation:backup.offsite*).
Risks / watchouts
Pulumi.foundation.yamlself-quotes scalars +encryptionsaltis now load-bearing (decrypts 3 committed secrets) — keep it committed; don't strip the salt anymore.- VM SSH is port 222; the eventual real VM would be 22 (
vm.sshPorthandles it). VERSIONSimages are:PIN_DIGEST+ RustFS islatest— pin before treating as production.- Don't run
pulumi upagainst the productionolsicloud4-*stacks. The home MinIO.localname is LAN-only; the VM must use the publicminio.wob.olsitec.de:19000. - Everything is destroyable:
provision(VM),offsite-backup(bucket+creds) viapulumi destroy.