Skip to content

Latest commit

 

History

History
97 lines (74 loc) · 3.73 KB

File metadata and controls

97 lines (74 loc) · 3.73 KB

hetzner/control-plane — Terraform for the eliza Cloud control-plane VMs

This Terraform module manages the persistent Hetzner Cloud VM(s) that host the elizaOS Cloud control-plane:

  • eliza-provisioning-worker — pulls jobs from the jobs table and SSHs into sandbox cores
  • eliza-agent-router — subdomain HTTP routing
  • cloudflared — secure tunnel for sandboxes.waifu.fun
  • headscale — VPN mesh for cross-core agent traffic

The data plane (the sandbox cores themselves) is not managed here — those are provisioned and drained at runtime by node-autoscaler.ts which talks to the Hetzner Cloud API directly. See ../ARCHITECTURE.md for the full split.

Prerequisites

  1. Hetzner Cloud project with API token (HCLOUD_TOKEN).
  2. Cloudflare account with API token + DNS edit on elizacloud.ai (CLOUDFLARE_API_TOKEN).
  3. Cloudflare R2 bucket eliza-terraform-state for remote state. Generate an R2 API token, edit backend-staging.hcl / backend-production.hcl with your CF account ID, then export the R2 token as AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY before terraform init.
  4. Terraform >= 1.5.0 locally.

Bootstrap a brand-new control-plane VM (staging)

cd packages/cloud-infra/cloud/terraform/hetzner/control-plane

# 1. Pull providers + connect remote state.
terraform init -backend-config=backend-staging.hcl

# 2. Copy + fill tfvars.
cp tfvars/staging.tfvars.example tfvars/staging.tfvars
$EDITOR tfvars/staging.tfvars

# 3. Plan + apply.
export HCLOUD_TOKEN=...
export CLOUDFLARE_API_TOKEN=...
terraform plan -var-file=tfvars/staging.tfvars
terraform apply -var-file=tfvars/staging.tfvars

# 4. Output gives you the VM IP. Copy the cloud env file into place:
scp packages/cloud-shared/.env.local root@<vm-ip>:/opt/eliza/cloud/.env.local

# 5. Trigger first deploy from GitHub Actions
#    (workflow: deploy-eliza-provisioning-worker.yml, manual dispatch).

Adopt the existing production VM into Terraform

The current prod manager VM (89.167.63.246, hostname milady) was created by-hand via packages/scripts/cloud/admin/bootstrap-provisioning-worker-host.mjs on May 7th. To bring it under Terraform without recreating it:

# 1. Look up the Hetzner Cloud server ID:
hcloud server list  # find the one with IP 89.167.63.246

# 2. Import the existing resource into state:
terraform init -backend-config=backend-production.hcl
terraform import \
  -var-file=tfvars/production.tfvars \
  'hcloud_server.control_plane["1"]' \
  <SERVER_ID>

# 3. Run `terraform plan` and adjust variables until the diff is empty.
#    Common drift: labels, ssh_keys (manually added during initial setup).

What this module does NOT manage (yet)

  • Headscale state (preauth keys, ACLs) — manual via headscale CLI.
  • Cloudflared tunnels — config lives at /root/.cloudflared/ on the VM and is created via cloudflared tunnel create one-shot.
  • The systemd units — installed by deploy-eliza-provisioning-worker.yml on every push.
  • The actual eliza Cloud sandbox cores (data plane) — runtime autoscale.

These are tracked as TODOs in ../ARCHITECTURE.md.

Cost

Component Resource Monthly (€)
1× cpx21 (3 vCPU / 4 GB) control VM ~5
1× IPv4 + IPv6 floating IP included
Cloudflare R2 state < 100 KB 0
Total per environment ~5

A 2nd control-plane VM (HA, currently unused) doubles the line. The data-plane autoscale cost is separate and elastic.