Deployment dependency rules ensure that one deployment succeeds before
another can proceed. Use them to coordinate related services, enforce deployment
order across microservices, or manage infrastructure dependencies.
Overview
Why Use Deployment Dependencies?
Deployment dependency rules help you:
- Coordinate services - Deploy database before API, API before frontend
- Manage infrastructure - Infrastructure changes before application updates
- Enforce order - Shared libraries before dependent services
- Reduce failures - Prevent cascading failures from out-of-order deploys
Configuration
Properties
deploymentDependency.dependsOn
CEL expression to match upstream release targets that must exist before this
deployment can proceed. The expression can reference both deployment and
version properties of the currently deployed upstream release.
Available CEL Variables
The dependsOn expression is evaluated against each release target on the same
resource that has a successful release. Both deployment.* and version.*
fields are available:
| Variable | Type | Description |
|---|
deployment.id | string | Deployment ID |
deployment.name | string | Deployment name |
deployment.slug | string | Deployment slug |
deployment.metadata | map | Deployment metadata key-value pairs |
version.id | string | Deployed version ID |
version.tag | string | Version tag (e.g. v2.1.0) |
version.name | string | Version name |
version.status | string | Version status |
version.metadata | map | Version metadata key-value pairs |
version.createdAt | timestamp | When the version was created |
How It Works
- Release created - A new version is released for a deployment with
dependency rules.
- Same-resource resolution - Ctrlplane finds all release targets on the
same resource as the current target.
- Version resolution - For each release target, Ctrlplane resolves the
deployment and its currently deployed version (from the latest successful
job).
- CEL evaluation - The
dependsOn expression is evaluated against each
{deployment, version} pair.
- Deployment allowed - If at least one upstream release target matches the
selector, the deployment can proceed.
Common Patterns
Database Before API
Ensure database migrations complete before API deploys:
Service Dependency Chain
Create a chain of dependencies:
Shared Library Dependencies
Ensure shared libraries are deployed before dependent services:
resource "ctrlplane_policy" "services_require_shared_lib" {
name = "Services Require Shared Lib"
selector = "deployment.metadata['usesSharedLib'] == 'true'"
deployment_dependency {
depends_on_selector = "deployment.metadata['type'] == 'shared-library'"
}
}
Version-Scoped Dependencies
Require a specific version range of an upstream deployment:
Depend on an upstream deployment running a version with specific metadata:
resource "ctrlplane_policy" "frontend_requires_stable_api" {
name = "Frontend Requires Stable API"
selector = "deployment.name == 'frontend'"
deployment_dependency {
depends_on_selector = "deployment.name == 'api-service' && version.metadata.channel == 'stable'"
}
}
Infrastructure First
Deploy infrastructure changes before application updates:
resource "ctrlplane_policy" "app_requires_infrastructure" {
name = "App Requires Infrastructure"
selector = "deployment.metadata['type'] == 'application'"
deployment_dependency {
depends_on_selector = "deployment.metadata['type'] == 'infrastructure'"
}
}
Multi-Service Dependency
Depend on multiple services using CEL in operator:
resource "ctrlplane_policy" "gateway_requires_services" {
name = "Gateway Requires Backend Services"
selector = "deployment.name == 'api-gateway'"
deployment_dependency {
depends_on_selector = "deployment.name in ['auth-service', 'user-service', 'billing-service']"
}
}
Combining with Other Rules
With Environment Progression
With Gradual Rollout
resource "ctrlplane_policy" "frontend_controlled_release" {
name = "Frontend Controlled Release"
selector = "deployment.name == 'frontend'"
deployment_dependency {
depends_on_selector = "deployment.name == 'api-service'"
}
gradual_rollout {
rollout_type = "linear"
time_scale_interval = 300
}
}
Best Practices
Dependency Design
| Pattern | Use Case |
|---|
| Database → API | Schema changes before code |
| API → Frontend | API contracts before consumers |
| Infrastructure → App | Platform changes before workloads |
| Shared lib → Services | Common code before dependents |
| Config → Application | Configuration before apps |
Recommendations
- ✅ Keep dependency chains short (2-3 levels max)
- ✅ Use metadata to group related deployments
- ✅ Document why dependencies exist
- ✅ Test dependency resolution in staging
- ✅ Monitor for circular dependency issues
Anti-Patterns
- ❌ Deep dependency chains (> 3 levels)
- ❌ Circular dependencies (A → B → A)
- ❌ Over-coupling unrelated services
- ❌ Using dependencies when environment progression would suffice
Troubleshooting
Deployment Blocked
If a deployment is blocked waiting for dependencies:
- Check the dependency deployment’s status
- Verify the CEL expression matches the expected deployment
- Remember that dependencies are resolved per-resource — the upstream
deployment must have a successful release on the same resource
- Review the dependency deployment’s success status
Circular Dependencies
If you encounter circular dependency errors:
- Review the dependency graph
- Break the cycle by removing one dependency
- Consider using environment progression instead
Next Steps