Dependency Management Guide
Resource ordering and dependency graphs in Tenant Operator.
Overview
Tenant Operator uses a DAG (Directed Acyclic Graph) to order resource creation and ensure dependencies are satisfied before applying resources.
Defining Dependencies
Use the dependIds field to specify dependencies:
Syntax
Set dependIds to an array of resource IDs. The controller ensures all referenced resources finish reconciling before applying the dependent resource.
deployments:
- id: app
dependIds: ["secret"] # Wait for secret first
nameTemplate: "{{ .uid }}-app"
spec:
# ... deployment specDependency Resolution
Topological Sort
Resources are applied in dependency order:
secret (no dependencies)
↓
app (depends on: secret)
↓
svc (depends on: app)Cycle Detection
Circular dependencies are rejected:
Why it fails
Dependency resolution uses a DAG. Any cycle blocks reconciliation and surfaces as DependencyError.
# ❌ This will fail
- id: a
dependIds: ["b"]
- id: b
dependIds: ["a"]Error: DependencyError: Dependency cycle detected: a -> b -> a
Common Patterns
Pattern 1: Secrets Before Apps
secrets:
- id: api-secret
nameTemplate: "{{ .uid }}-secret"
# No dependencies
deployments:
- id: app
dependIds: ["api-secret"] # Wait for secretPattern 2: ConfigMap Before Deployment
configMaps:
- id: app-config
nameTemplate: "{{ .uid }}-config"
deployments:
- id: app
dependIds: ["app-config"] # Wait for configmapPattern 3: App Before Service
deployments:
- id: app
# No dependencies
services:
- id: svc
dependIds: ["app"] # Wait for deployment firstPattern 4: PVC Before StatefulSet
persistentVolumeClaims:
- id: data-pvc
# No dependencies
statefulSets:
- id: stateful-app
dependIds: ["data-pvc"] # Wait for PVCReadiness Gates
Use waitForReady to wait for resource readiness:
Combine readiness and dependencies
dependIds only guarantees creation order. Enable waitForReady to ensure ready status before dependent workloads roll out.
deployments:
- id: db
waitForReady: true
timeoutSeconds: 300
deployments:
- id: app
dependIds: ["db"] # Wait for db to exist AND be ready
waitForReady: trueBest Practices
1. Shallow Dependencies
Prefer shallow dependency trees:
Good (depth: 2):
secret
├─ app
│ └─ svc
└─ db
└─ db-svcBad (depth: 5):
secret → config → pvc → db → db-svc → app2. Parallel Execution
Independent resources execute in parallel:
deployments:
- id: app-a
dependIds: ["secret"] # Both execute in parallel
- id: app-b
dependIds: ["secret"] # Both execute in parallel3. Minimal Dependencies
Only specify necessary dependencies:
Good:
- id: app
dependIds: ["secret"] # Only essential dependencyBad:
- id: app
dependIds: ["secret", "unrelated-resource"] # Unnecessary waitDebugging Dependencies
Common Errors
Cycle detected
DependencyError: Dependency cycle detected: a -> b -> c -> aFix: Remove or refactor at least one edge so the graph becomes acyclic.
Missing dependency
DependencyError: Resource 'app' depends on 'missing-id' which does not existFix: Ensure every dependIds entry references a defined resource ID.
Readiness timeout
ReadinessTimeout: Resource db not ready within 300sFix: Increase timeoutSeconds or set waitForReady: false when readiness should not block dependent resources.
