Routing Service
Atomic ingress route and gateway configuration management
Routing Service
The RoutingService manages atomic ingress route assignments.
Location: go/apps/ctrl/workflows/routing/
Proto: go/proto/hydra/v1/routing.proto
Key: project_id
Why Separate Service?
Ingress route and gateway operations are the critical section of deployments:
- Must be atomic - both succeed or both fail
- Must be serialized per project to prevent race conditions
- Should not block non-routing operations (like building containers)
By separating routing, we:
- Allow multiple deployments to build in parallel
- Serialize only the sensitive routing mutations
- Provide clear boundaries for concurrency control
Operations
AssignIngressRoutes
flowchart TD
Start([AssignIngressRoutes]) --> LoopRoutes{For Each Route}
LoopRoutes --> FindRoute[Find or Create Ingress Route]
FindRoute --> NextRoute
NextRoute --> LoopRoutes
LoopRoutes --> UpdateDeployment[Update Deployment ID]
UpdateDeployment --> End([Return Success])
style UpdateDeployment fill:#e1f5fe
Creates or reassigns ingress routes to a deployment:
- For each ingress route ID: update the deployment ID
- Routes are pre-created with hostnames and sticky behavior
- This operation simply points them to the new deployment
- Per-tenant gateways handle the actual traffic routing
Implementation: go/apps/ctrl/workflows/routing/assign_ingress_routes_handler.go
Ingress Route Sticky Levels:
BRANCH: Branch-level (e.g.,main.domain.com)ENVIRONMENT: Environment-level (e.g.,staging.domain.com)LIVE: Production domain (e.g.,domain.com)
Per-Tenant Gateway Architecture
With the new per-tenant gateway model:
- Each environment has its own gateway instances
- Ingress routes point to deployments within an environment
- Gateway configuration is managed at the environment level
- This provides better isolation and scaling characteristics
Local Domain Filtering
Hostnames with .local or .test TLDs, or localhost/127.0.0.1 are typically excluded from production routing since they're for local development only.