Skip to content

Beast VM Lifecycle

The Beast (cx53 x86_64, 16 vCPU, 32 GB RAM) is an ephemeral compute node -- created when needed, destroyed when done. It embodies the cattle-not-pets principle: no persistent state, fully automated provisioning, disposable by design.

ARM to x86 switch (2026-04-15)

Originally planned as CAX31 (ARM64, 4 vCPU, 8 GB). Switched to cx53 (x86, 16 vCPU, 32 GB) during first deployment because cx53 is cheaper per hour for ephemeral use AND eliminates ARM image compatibility issues. See ADR-009.

Spin-Up Procedure

flowchart LR
    A[tofu apply] --> B[Wait for boot]
    B --> C[Ansible bootstrap]
    C --> D[K3s agent join]
    D --> E[Fleet sync]
    E --> F[Ready]

    style A fill:#1e8449,stroke:#27ae60,color:#fff
    style F fill:#1e8449,stroke:#27ae60,color:#fff

Run ./scripts/beast-up.sh which executes these 10 steps:

Step Action Duration
1 tofu apply -target=hcloud_server.beast -- create cx53 VM (without firewall) ~30s
2 tofu apply -target=hcloud_server_network.beast -- attach private network ~5s
3 Wait for SSH availability on 10.0.1.3:2222 (via Hub jump) ~30s
4 ansible-playbook -l beast site.yml -- OS hardening, packages, CrowdSec ~90s
5 Install K3s agent, join cluster via 10.0.1.1:6443 ~45s
6 Apply node label lron/role=beast ~2s
7 Wait for node status Ready ~30s
8 Fleet auto-deploys fleet/dev/ workloads to Beast ~30s
9 Verify pod health on Beast node ~10s
10 Log start time to ~/.beast-session.log on Hub ~1s

Total spin-up time: ~5 minutes

Spin-Down Procedure

Run ./scripts/beast-down.sh which executes these 8 steps:

Step Action Duration
1 Cordon Beast node (kubectl cordon beast) ~2s
2 Drain Beast node (kubectl drain beast --ignore-daemonsets --delete-emptydir-data) ~15s
3 Wait for all Beast pods to terminate ~10s
4 Remove K3s agent node from cluster (kubectl delete node beast) ~2s
5 tofu destroy -target=hcloud_server_network.beast -- detach network ~5s
6 tofu destroy -target=hcloud_server.beast -- destroy VM ~15s
7 Log end time + session duration to ~/.beast-session.log on Hub ~1s
8 Calculate and display session cost (duration x EUR 0.0360/h) ~1s

Total spin-down time: ~1 minute

Watchdog Rules

To prevent runaway costs, the following safeguards are in place:

Rule Mechanism Action
Max session duration Cron job on Hub checks beast-session.log Alert via ntfy after 8h, auto-destroy after 12h
Budget ceiling Monthly hour tracking in session log Alert at 50h, hard stop at 80h
Orphan detection vmalert rule: node absent > 30min without drain Alert via ntfy
Cost display beast-down.sh prints session cost Awareness

No auto-destroy on idle

The watchdog does NOT auto-destroy on idle -- only on excessive duration. This avoids killing long-running builds. The operator must explicitly run beast-down.sh.

Cattle vs Pets Comparison

Aspect Pet (traditional VM) Cattle (Beast)
Provisioning Manual setup, snowflake config Automated from code
State Local data, local config No local state -- all in Git or Hub
Identity Named, irreplaceable Disposable, recreated from scratch
Backup Required Not needed
Failure response Diagnose and repair Destroy and recreate
Lifecycle Months to years Hours to days
Cost model Monthly subscription Hourly pay-per-use
Configuration drift Accumulates over time Impossible (rebuilt each time)

Cost Analysis

Scenario Hours/Month Hourly Rate Monthly Cost Annual Cost
Light use (weekends only) 20h EUR 0.0360 EUR 0.72 EUR 8.64
Budget target 40h EUR 0.0360 EUR 1.44 EUR 17.28
Normal use (3x/week, 4h) 48h EUR 0.0360 EUR 1.73 EUR 20.74
Heavy use (daily, 4h) 120h EUR 0.0360 EUR 4.32 EUR 51.84
Always on (for comparison) 730h EUR 0.0360 EUR 26.28 EUR 315.36

Savings vs always-on

At the budget target of 40h/month, Beast costs EUR 1.44 instead of EUR 26.28 -- a 95% saving compared to running it 24/7. The cx53 provides 16 vCPU and 32 GB RAM -- serious compute power -- for less than EUR 2/month.