From f04a072beb35863b51b23d77bba1dbb8ffbae5bb Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Mon, 9 Feb 2026 21:03:57 +0000 Subject: [PATCH] [ci skip] Add internal OSM routing services (OSRM foot, bicycle, OTP) New osm-routing namespace with walking, cycling, and transit routing services for the real-estate-crawler. Internal-only (no public ingress). --- modules/kubernetes/main.tf | 11 +- modules/kubernetes/osm-routing/main.tf | 227 ++++++++++++++++++ .../kubernetes/real-estate-crawler/main.tf | 24 ++ 3 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 modules/kubernetes/osm-routing/main.tf diff --git a/modules/kubernetes/main.tf b/modules/kubernetes/main.tf index 077f0de4..49c58073 100644 --- a/modules/kubernetes/main.tf +++ b/modules/kubernetes/main.tf @@ -149,7 +149,7 @@ locals { "url", "excalidraw", "travel_blog", "dashy", "send", "ytdlp", "wealthfolio", "rybbit", "stirling-pdf", "networking-toolbox", "navidrome", "freshrss", "forgejo", "tor-proxy", "real-estate-crawler", "n8n", "changedetection", "linkwarden", "matrix", "homepage", "meshcentral", "diun", "cyberchef", "ntfy", "ollama", - "servarr", "jsoncrack", "paperless-ngx", "frigate", "audiobookshelf", "tandoor", "ebook2audiobook", "netbox", "speedtest", "resume", "freedify", "mcaptcha", "affine", "plotting-book", "whisper", "grampsweb" + "servarr", "jsoncrack", "paperless-ngx", "frigate", "audiobookshelf", "tandoor", "ebook2audiobook", "netbox", "speedtest", "resume", "freedify", "mcaptcha", "affine", "plotting-book", "whisper", "grampsweb", "osm-routing" ], } active_modules = distinct(flatten([ @@ -905,6 +905,15 @@ module "real-estate-crawler" { depends_on = [null_resource.core_services] } +module "osm_routing" { + source = "./osm-routing" + for_each = contains(local.active_modules, "osm-routing") ? { osm-routing = true } : {} + tls_secret_name = var.tls_secret_name + tier = local.tiers.aux + + depends_on = [null_resource.core_services] +} + module "tor-proxy" { source = "./tor-proxy" for_each = contains(local.active_modules, "tor-proxy") ? { tor-proxy = true } : {} diff --git a/modules/kubernetes/osm-routing/main.tf b/modules/kubernetes/osm-routing/main.tf new file mode 100644 index 00000000..8fd54627 --- /dev/null +++ b/modules/kubernetes/osm-routing/main.tf @@ -0,0 +1,227 @@ +variable "tls_secret_name" {} +variable "tier" { type = string } + +resource "kubernetes_namespace" "osm-routing" { + metadata { + name = "osm-routing" + labels = { + "istio-injection" : "disabled" + } + } +} + +# --- OSRM Foot --- +resource "kubernetes_deployment" "osrm-foot" { + metadata { + name = "osrm-foot" + namespace = kubernetes_namespace.osm-routing.metadata[0].name + labels = { + app = "osrm-foot" + tier = var.tier + } + } + spec { + replicas = 1 + strategy { + type = "Recreate" + } + selector { + match_labels = { + app = "osrm-foot" + } + } + template { + metadata { + labels = { + app = "osrm-foot" + } + } + spec { + container { + name = "osrm-foot" + image = "ghcr.io/project-osrm/osrm-backend:latest" + command = ["osrm-routed", "--algorithm", "MLD", "/data/foot/greater-london-latest.osrm"] + port { + name = "http" + container_port = 5000 + protocol = "TCP" + } + volume_mount { + name = "osrm-data" + mount_path = "/data" + } + } + volume { + name = "osrm-data" + nfs { + server = "10.0.10.15" + path = "/mnt/main/osm-routing/osrm-data" + } + } + } + } + } +} + +resource "kubernetes_service" "osrm-foot" { + metadata { + name = "osrm-foot" + namespace = kubernetes_namespace.osm-routing.metadata[0].name + labels = { + app = "osrm-foot" + } + } + spec { + selector = { + app = "osrm-foot" + } + port { + port = 5000 + target_port = 5000 + } + } +} + +# --- OSRM Bicycle --- +resource "kubernetes_deployment" "osrm-bicycle" { + metadata { + name = "osrm-bicycle" + namespace = kubernetes_namespace.osm-routing.metadata[0].name + labels = { + app = "osrm-bicycle" + tier = var.tier + } + } + spec { + replicas = 1 + strategy { + type = "Recreate" + } + selector { + match_labels = { + app = "osrm-bicycle" + } + } + template { + metadata { + labels = { + app = "osrm-bicycle" + } + } + spec { + container { + name = "osrm-bicycle" + image = "ghcr.io/project-osrm/osrm-backend:latest" + command = ["osrm-routed", "--algorithm", "MLD", "/data/bicycle/greater-london-latest.osrm"] + port { + name = "http" + container_port = 5000 + protocol = "TCP" + } + volume_mount { + name = "osrm-data" + mount_path = "/data" + } + } + volume { + name = "osrm-data" + nfs { + server = "10.0.10.15" + path = "/mnt/main/osm-routing/osrm-data" + } + } + } + } + } +} + +resource "kubernetes_service" "osrm-bicycle" { + metadata { + name = "osrm-bicycle" + namespace = kubernetes_namespace.osm-routing.metadata[0].name + labels = { + app = "osrm-bicycle" + } + } + spec { + selector = { + app = "osrm-bicycle" + } + port { + port = 5000 + target_port = 5000 + } + } +} + +# --- OTP (OpenTripPlanner) --- +resource "kubernetes_deployment" "otp" { + metadata { + name = "otp" + namespace = kubernetes_namespace.osm-routing.metadata[0].name + labels = { + app = "otp" + tier = var.tier + } + } + spec { + replicas = 1 + strategy { + type = "Recreate" + } + selector { + match_labels = { + app = "otp" + } + } + template { + metadata { + labels = { + app = "otp" + } + } + spec { + container { + name = "otp" + image = "opentripplanner/opentripplanner:2.6.0" + args = ["--build", "--save"] + port { + name = "http" + container_port = 8080 + protocol = "TCP" + } + volume_mount { + name = "otp-data" + mount_path = "/var/opentripplanner" + } + } + volume { + name = "otp-data" + nfs { + server = "10.0.10.15" + path = "/mnt/main/osm-routing/otp-data" + } + } + } + } + } +} + +resource "kubernetes_service" "otp" { + metadata { + name = "otp" + namespace = kubernetes_namespace.osm-routing.metadata[0].name + labels = { + app = "otp" + } + } + spec { + selector = { + app = "otp" + } + port { + port = 8080 + target_port = 8080 + } + } +} diff --git a/modules/kubernetes/real-estate-crawler/main.tf b/modules/kubernetes/real-estate-crawler/main.tf index 6fa29d6c..450b2e26 100644 --- a/modules/kubernetes/real-estate-crawler/main.tf +++ b/modules/kubernetes/real-estate-crawler/main.tf @@ -159,6 +159,18 @@ resource "kubernetes_deployment" "realestate-crawler-api" { name = "UVICORN_LOG_LEVEL" value = "debug" } + env { + name = "OSRM_FOOT_URL" + value = "http://osrm-foot.osm-routing.svc.cluster.local:5000" + } + env { + name = "OSRM_BICYCLE_URL" + value = "http://osrm-bicycle.osm-routing.svc.cluster.local:5000" + } + env { + name = "OTP_URL" + value = "http://otp.osm-routing.svc.cluster.local:8080" + } env { name = "SLACK_WEBHOOK_URL" value = var.notification_settings["slack"] @@ -325,6 +337,18 @@ resource "kubernetes_deployment" "realestate-crawler-celery" { name = "SLACK_WEBHOOK_URL" value = lookup(var.notification_settings, "slack", "") } + env { + name = "OSRM_FOOT_URL" + value = "http://osrm-foot.osm-routing.svc.cluster.local:5000" + } + env { + name = "OSRM_BICYCLE_URL" + value = "http://osrm-bicycle.osm-routing.svc.cluster.local:5000" + } + env { + name = "OTP_URL" + value = "http://otp.osm-routing.svc.cluster.local:8080" + } volume_mount { name = "data" mount_path = "/app/data"