diff --git a/servers/legion/main.tf b/servers/legion/main.tf index 6b399b8..764ca3b 100644 --- a/servers/legion/main.tf +++ b/servers/legion/main.tf @@ -10,6 +10,10 @@ terraform { source = "hashicorp/helm" version = "~> 2.14" } + cloudflare = { + source = "cloudflare/cloudflare" + version = "~> 4.0" + } } backend "s3" { @@ -35,3 +39,63 @@ provider "helm" { 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_tunnel_config" "legion" { + account_id = var.cloudflare_account_id + tunnel_id = var.cloudflare_tunnel_id + + config { + # neuron.neuralplatform.ai — MCP server (SSE transport, requires CF-Access headers) + ingress_rule { + hostname = "neuron.neuralplatform.ai" + service = "https://traefik.kube-system.svc:443" + origin_request { + no_tls_verify = true + } + } + + ingress_rule { + hostname = "vault.neuralplatform.ai" + service = "https://traefik.kube-system.svc:443" + origin_request { + no_tls_verify = true + } + } + + ingress_rule { + hostname = "watch.nook.family" + service = "https://traefik.kube-system.svc:443" + origin_request { + no_tls_verify = true + } + } + + ingress_rule { + hostname = "jellyfin.nook.family" + service = "https://traefik.kube-system.svc:443" + origin_request { + no_tls_verify = true + } + } + + ingress_rule { + hostname = "bazarr.nook.family" + service = "https://traefik.kube-system.svc:443" + origin_request { + no_tls_verify = true + } + } + + # Catch-all — must be last + ingress_rule { + service = "http_status:404" + } + } +} diff --git a/servers/legion/variables.tf b/servers/legion/variables.tf index a3ab42d..0f0e601 100644 --- a/servers/legion/variables.tf +++ b/servers/legion/variables.tf @@ -39,3 +39,15 @@ variable "gitea_api_token" { type = string sensitive = true } + +variable "cloudflare_tunnel_id" { + description = "Cloudflare tunnel ID (main legion tunnel)" + type = string + sensitive = true +} + +variable "cloudflare_account_id" { + description = "Cloudflare account ID" + type = string + sensitive = true +}