Skip to content

Region Onboarding

The end-to-end flow for standing up region N+1 — infrastructure, telemetry, registry, first cluster, registration, go-live. Actor at MVP: an operator with Terraform, talosctl, and one admin endpoint; the post-MVP automation owner is noted per stage. The primary flow is a DigitalOcean region; each stage carries its non-DO delta inline. (Design record: specs/2026-07-11-region-onboarding-dns-design.md.)

The region model — factories are code, regions are data

Adding a cloud is a code event: one adapter factory per cloud (§10), unavoidable. Adding a region on a supported cloud is a data + infrastructure event — no Starbase deploy. (The Crossplane Provider/ProviderConfig split; same pattern §11 already uses for integrations.)

A region row carries identity, lifecycle, and wiring — never credentials (those live in the §39.1 #18 encrypted catalog, keyed by region):

regions table · Starbase Postgres (defines the §39.1 #1 regions entry)
regions (
    id                  TEXT PRIMARY KEY,     -- "nyc3", "fra1"
    display_name        TEXT NOT NULL,        -- "Frankfurt"
    cloud               TEXT NOT NULL,        -- "digitalocean" — must match a registered adapter factory
    status              TEXT CHECK (status IN ('provisioning', 'active', 'draining')),
    transport           TEXT CHECK (transport IN ('peering', 'massrelay')),   -- §39.3 #43
    vpc_cidr            CIDR NOT NULL,        -- the regional /16 (stage 0)
    clickhouse_endpoint TEXT NOT NULL,        -- telemetry read/write front-door (stage 2)
    registry_endpoint   TEXT NOT NULL,        -- per-region registry (stage 3)
    created_at          TIMESTAMPTZ DEFAULT NOW()
);

At startup Starbase hydrates each row through its cloud's adapter factory into the §12 Region struct.

Registration — manifest → validated endpoint

A region manifest (YAML, living in the infra repo next to the Terraform that built the region, PR-reviewed) is applied to an operator-authenticated admin endpoint:

Region manifest · infra repo · applied via POST /internal/regions
id: fra1
display_name: Frankfurt
cloud: digitalocean
transport: peering            # massrelay on clouds without DO peering
vpc_cidr: 10.20.0.0/16
clickhouse_endpoint: 10.20.0.5:9440
registry_endpoint: registry.digitalocean.com/starform-fra1

Starbase validates before writing: an adapter factory exists for cloud; the transport is valid; live connectivity probes pass (ClickHouse read login; registry reachable; for massrelay, the stream is up). Only then does the row land — status: provisioning. The same endpoint owns status transitions; active is flipped only after the go-live gate below. Raw SQL and boot-time config files are rejected shapes: no validation, no lifecycle, restart-to-add, file↔DB drift.

The stages

Stage 0 — Allocate. Pick the region ID; check DO quota headroom ahead of need via the reseller-partnership runbook (§39.3 #47); pick the regional /16one tfvars line. All regional VPCs peer the same control-plane VPC, so ranges must be mutually non-overlapping; the Terraform vars file is the ledger — no IPAM system (this absorbs §39.3 #46). Non-DO: quota per that cloud; the non-overlap constraint doesn't bind (no peering), but keep ranges clean anyway.

Stage 1 — Network. Terraform creates the regional VPC; create the control-plane ↔ region VPC peering and verify routes (§4.4). Peering is used wherever the cloud supports it. Non-DO: DO peering cannot reach other clouds — the region's transport is Mass Relay, deployed in stage 5 (§39.3 #43).

Stage 2 — Telemetry + jump droplets. Terraform provisions two droplets:

  • Telemetry droplet (the single v2 store): bring up ClickHouse in the v2 order — retention dictionary → tables → users → OTel gateway (v2 Bootstrap). The three ClickHouse credentials (otel_ingest, starbase_read, starbase_write) go into the encrypted catalog, keyed by region.
  • Jump droplet (hardened, SSH-only): the region's talosctl seat. The regional talosconfig lives only there (per-region blast radius); post-MVP Shipyard installs onto this same box. The Talos API stays VPC-private, never public.

Non-DO: identical, on that cloud's VMs.

Stage 3 — Registry. Create the region's container registry (§16.2: one per region). Push credentials → Starbase (builds push via the placement region's RegistryProvider); pull credentials staged for cluster bootstrap (the registry-<name> pull secret, §26.3). Non-DO: that cloud's registry via its adapter.

Stage 4 — First customer cluster. The existing bootstrap, unchanged, run from the jump droplet (§26.3, §39.3 #26):

  • Talos (gVisor + LUKS2) → etcd → Cilium → DO CCM/CSI → metrics-server/KSM → Envoy Gateway → OTel node agent, Alloy, Shuttle → etcd-backup CronJob → DO Spaces.
  • Envoy Gateway's Service makes the CCM provision the LB; the Cloudflare Origin Certificate installs as the listener Secret (the same cert every region).
  • Record the LB IP on the cluster row — it becomes the target for this region's service DNS records (DNS & Domains).
  • Cluster identity is minted here — the token flow and tables below.

Non-DO: that cloud's CCM/CSI + the Talos image-import pipeline — readiness spikes, §39.3 #73.

Stage 5 — Register the region. The manifest → validated endpoint flow above; cluster rows registered under the region with the LB IP. Non-DO: transport: massrelay — deploy the agent (two replicas, two streams) on the telemetry droplet with its minted token; validation probes the stream instead of the direct connection.

Stage 6 — Go-live gate. Deploy a canary service through the normal customer pipeline — one test that exercises everything: build pushes to the new registry → Shuttle applies → the per-hostname DNS record is created → a request flows Cloudflare → LB → Envoy → pod → logs and the 7 metrics render in Stardeck over the region's transport → billing snapshots arrive → the cluster's Grafana-Cloud liveness series exists and the §39.2 #64 droplet scrape is wired. All green → the operator flips status: active; placement (FR-077) can now select the region.

Token minting

Cluster identity is minted by the same admin surface at cluster registration (stage 4/5), making §14's "registers cluster as active" concrete — mint → deliver → register:

Token Consumer Delivered via
cluster_id (UUID) Shuttle config (§23) Bootstrap
Shuttle bearer token Starbase API auth (§25) Bootstrap Secret (STARFORM_AUTH_TOKEN_FILE)
Telemetry ingest token (FR-066) Regional OTel gateway's token file Bootstrap Secret + gateway config append

Tables — clusters & tokens

Infra · clusters + minted tokens · Starbase Postgres
clusters (
    id                     UUID PRIMARY KEY,
    region_id              TEXT NOT NULL REFERENCES regions(id),
    name                   TEXT NOT NULL,       -- "fra1-c1"
    status                 TEXT NOT NULL CHECK (status IN ('provisioning','active','cordoned','draining')),
    lb_ip                  INET,                -- the region's service-DNS record target (DNS & Domains)
    desired_state_sequence BIGINT NOT NULL DEFAULT 0,   -- §25.1 monotonic counter (restore path §25.4)
    pod_soft_limit         INT NOT NULL DEFAULT 1000,   -- §7 scaling threshold input
    last_capacity_report   JSONB,               -- §25.3 upsert
    created_at             TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE (region_id, name)
);

cluster_tokens (            -- minted at cluster registration (token flow above)
    id          UUID PRIMARY KEY,
    cluster_id  UUID NOT NULL REFERENCES clusters(id) ON DELETE CASCADE,
    kind        TEXT NOT NULL CHECK (kind IN ('shuttle', 'ingest')),   -- §25 auth · FR-066
    token_hash  TEXT NOT NULL,      -- SHA-256; plaintext shown once at mint
    created_at  TIMESTAMPTZ DEFAULT NOW(),
    revoked_at  TIMESTAMPTZ
);

What lives where — the residency boundary

What a region does and doesn't localize — the honest answer to "is my data in region X?":

Where What
In-region Customer workloads · databases · buckets (when the Tigris primitive ships) · logs + metrics · container images
Central (control-plane region) All metadata · Var Group values/secrets (encrypted, control-plane Postgres) · billing records
Transits US/EU Source code + build artifacts (the Worker clones centrally; Depot builds in AWS us-east-1 / eu-central-1, §16.8)

Posture: Starform provides runtime and data residency per region — application metadata, secrets, and the build pipeline are centralized. Full-stack residency (in-region builds, regional metadata) is Enterprise-tier territory and not offered now; if a deal ever requires it, the path is the in-region self-hosted-BuildKit adapter (§16.9 trigger #3, §16.10). GDPR/data-retention work: §39.2 #22.

Non-DO deltas at a glance

Same skeleton, four substitutions: the cloud's adapter set (a prior code event, §10) · Mass Relay instead of peering (stages 1/5) · the cloud's CCM/CSI on self-managed Talos · the Talos image-import pipeline for that cloud. The last two are unverified — readiness spikes tracked as §39.3 #73; build them with the first non-DO region, not before.


Cross-references

Region registry & Region struct → §12 · the admin surface lives in the API binary → §13 · per-region transport → §39.3 #43 · VPC & peering → §4.4 · hostname → region → DNS & Domains · cluster bootstrap detail → §26.3 · telemetry bring-up → Observability v2 · Bootstrap · scaling within a region → §7. Canonical map: Canonical Sources.