Files
infrastructure/servers/legion/main.tf
Will Anderson 48106b27ec vault: cut over to GCE Raft HA cluster, retire nook.family media stack
- dns-neuralplatform.tf: add vault.neuralplatform.ai A record → 34.54.164.21 (GCP LB)
  DNS-only (not proxied) so GCP managed TLS cert can provision correctly
- main.tf: remove vault.neuralplatform.ai from Cloudflare tunnel ingress
  (now served directly via GCP Global HTTPS LB)
- main.tf: remove watch.nook.family, jellyfin.nook.family, bazarr.nook.family
  from tunnel ingress (nook.family media stack retired; infra is Neuron-focused)

GCE Vault cluster already initialized and running (3-node Raft, active since
2026-05-04T16:05). Secrets migrated 48/48 from k3s vault. ESO ClusterSecretStore
validated against new vault. k3s vault-0 is now superseded.
2026-05-04 16:40:03 -05:00

268 lines
7.5 KiB
Terraform

terraform {
required_version = ">= 1.5"
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.30"
}
helm = {
source = "hashicorp/helm"
version = "~> 2.14"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "legion-terraform-state"
key = "legion/terraform.tfstate"
region = "auto"
endpoint = "https://651161e0a3d321561b4c90b5bcd5f15b.r2.cloudflarestorage.com"
# R2 is S3-compatible but not AWS — skip AWS-specific checks
skip_credentials_validation = true
skip_metadata_api_check = true
skip_region_validation = true
force_path_style = true
}
}
provider "kubernetes" {
config_path = var.kubeconfig_path
}
provider "helm" {
kubernetes {
config_path = var.kubeconfig_path
}
}
provider "cloudflare" {
email = var.cloudflare_email
api_key = var.cloudflare_api_key
}
# Cloudflare tunnel ingress rules — all hostnames that route through the legion tunnel
# Catch-all (http_status:404) is implicit and always last; managed by Cloudflare API
resource "cloudflare_zero_trust_tunnel_cloudflared_config" "legion" {
account_id = var.cloudflare_account_id
tunnel_id = var.cloudflare_tunnel_id
config {
# neuron.neuralplatform.ai — MCP server, stable prod
ingress_rule {
hostname = "neuron.neuralplatform.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# neuron-alpha.neuralplatform.ai — experiment zone 1 (CI auto-deploys here)
ingress_rule {
hostname = "neuron-alpha.neuralplatform.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# neuron-beta.neuralplatform.ai — experiment zone 2
ingress_rule {
hostname = "neuron-beta.neuralplatform.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# neuron-gamma.neuralplatform.ai — experiment zone 3
ingress_rule {
hostname = "neuron-gamma.neuralplatform.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# vault.neuralplatform.ai — moved to GCP Global HTTPS LB (34.54.164.21)
# DNS is now a direct A record (not proxied) in dns-neuralplatform.tf
# watch.nook.family, jellyfin.nook.family, bazarr.nook.family — removed
# This infrastructure is focused on Neuron; nook.family media stack retired
# fornax.neuralplatform.ai — Fornax torrent coordinator (qBittorrent API proxy)
ingress_rule {
hostname = "fornax.neuralplatform.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# git.neuralplatform.ai — Gitea web UI (HTTP via Traefik)
ingress_rule {
hostname = "git.neuralplatform.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# ssh.git.neuralplatform.ai — Gitea SSH (direct to NodePort 30022)
ingress_rule {
hostname = "ssh.git.neuralplatform.ai"
service = "ssh://localhost:30022"
}
# neuron.neurontechnologies.ai — Neuron MCP (private, neuron-prod namespace)
ingress_rule {
hostname = "neuron.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# neurontechnologies.ai — Neuron Technologies prod (neuron-prod namespace)
ingress_rule {
hostname = "neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
ingress_rule {
hostname = "www.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# dev.neurontechnologies.ai — Neuron Technologies dev (neuron-dev namespace)
ingress_rule {
hostname = "dev.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# stage.neurontechnologies.ai — Neuron Technologies stage (neuron-stage namespace)
ingress_rule {
hostname = "stage.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# alpha.neurontechnologies.ai — experiment zone 1 (CI auto-deploys here)
ingress_rule {
hostname = "alpha.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# beta.neurontechnologies.ai — experiment zone 2
ingress_rule {
hostname = "beta.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# gamma.neurontechnologies.ai — experiment zone 3
ingress_rule {
hostname = "gamma.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# api.neurontechnologies.ai — Neuron REST backend (neuron-rest service)
ingress_rule {
hostname = "api.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# dharma.neurontechnologies.ai — DHARMA CGI registry
ingress_rule {
hostname = "dharma.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# sign.neurontechnologies.ai — Docuseal e-signature
ingress_rule {
hostname = "sign.neurontechnologies.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# sign.neuralplatform.ai — Docuseal temporary (license transfer)
ingress_rule {
hostname = "sign.neuralplatform.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# registry.neuralplatform.ai — Docker container registry (no Cloudflare buffering)
ingress_rule {
hostname = "registry.neuralplatform.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
disable_chunked_encoding = true
}
}
# vpn.neuralplatform.ai — Headscale coordination server (Tailscale control plane)
# Route directly to Headscale — bypasses Traefik which strips the Upgrade: ts2021 header
# Cloudflare handles TLS termination; internal connection is plain HTTP
ingress_rule {
hostname = "vpn.neuralplatform.ai"
service = "http://headscale.headscale.svc.cluster.local:8080"
}
# web-stage.neuralplatform.ai — Phase 1 Legion deploy of neuron-web
# (native El landing server). Routes via Traefik to the neuron-web
# service in the neuron-web namespace.
ingress_rule {
hostname = "web-stage.neuralplatform.ai"
service = "https://traefik.kube-system.svc:443"
origin_request {
no_tls_verify = true
}
}
# Catch-all — must be last
ingress_rule {
service = "http_status:404"
}
}
}