infra: add Headscale — self-hosted Tailscale control plane

- headscale.tf: namespace + 1Gi PVC for SQLite state
- apps/headscale.yaml: Deployment (headscale/headscale:0.23) + Service + ConfigMap
  - server_url: https://headscale.neuralplatform.ai
  - sqlite3 backend, DERP via Tailscale's map
  - MagicDNS base: vpn.neuralplatform.ai
- Cloudflare tunnel: headscale.neuralplatform.ai → headscale.headscale.svc:8080
- DNS CNAME added via API

Next: install tailscaled on Legion host, enroll as subnet router
This commit is contained in:
Will Anderson
2026-03-25 07:59:46 -05:00
parent 1312be1a03
commit 5334881d3f
2 changed files with 146 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
# Headscale — self-hosted Tailscale control plane
# Coordination endpoint: https://headscale.neuralplatform.ai (Cloudflare tunnel)
# Clients: Tailscale app on Mac/iOS/Android, pointed at custom server
# Subnet router: tailscaled on Legion host, advertises k3s + LAN CIDRs
resource "kubernetes_namespace" "headscale" {
metadata {
name = "headscale"
labels = {
managed-by = "terraform"
tier = "infrastructure"
}
}
}
resource "kubernetes_persistent_volume_claim" "headscale_data" {
metadata {
name = "headscale-data"
namespace = kubernetes_namespace.headscale.metadata[0].name
}
# wait_until_bound = false because local-path only provisions on pod schedule
wait_until_bound = false
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = "1Gi"
}
}
}
}