A Kubernetes operator that introduces declarative release gates before application rollouts.
It ensures that required pre-release steps — such as database migrations, data backfills, smoke tests, or validation jobs — run before new application versions are deployed.
All without requiring changes to CI pipelines or application startup logic.
The operator supports two modes:
- ReleaseManagedDeployment (CRD-based, recommended) — no webhooks, no cert-manager
- Deployment annotation mode (webhook-based, optional) — works with existing Deployments
Modern applications often require preconditions before a new version can safely roll out:
- Database schema migrations
- Data migrations or backfills
- Cache warmups
- Smoke tests
- Compliance or validation checks
Without orchestration:
- Pods may start before migrations complete
- Rollbacks require unsafe or stateful behavior
- CI pipelines become complex and environment-aware
- Init containers behave poorly during rolling updates
- There is no clean blocking mechanism in native Deployments
Release Gate Operator moves release orchestration into Kubernetes, where it belongs.
It acts as a deployment gatekeeper — a rollout only proceeds once declared pre-release steps succeed.
The most common use case is:
Safely coordinating database schema migrations with application rollouts.
However, the operator is intentionally generic and can run any Kubernetes Job as a blocking release gate.
Image tag changes
↓
Operator detects desired state change
↓
Blocking Gate Job runs
↓
If Job succeeds → Deployment rollout proceeds
If Job fails → Rollout is blocked
The operator guarantees ordering and gating, not business logic or migration semantics.
- Runs pre-release Jobs before new application versions are deployed
- Supports rollouts driven by image tag changes
- Works with GitOps (Flux / Argo CD friendly)
- No CI coupling — CI only builds and pushes images
- Failures block rollouts safely
- Rollbacks are naturally handled
- Works with Alembic, DBmate, Goose, or any custom command
- No dependency on specific migration tools
- Kubernetes >= 1.25
- Permissions to install CRDs and cluster-scoped RBAC
- cert-manager (only required for webhook mode)
Download the release-gate-operator.yaml from a release and apply:
kubectl apply --server-side --force-conflicts -f release-gate-operator.yamlThis installs:
- CRDs
- RBAC
- Controller Deployment
⚠️ Requires cert-manager to be installed in the cluster.
Download the release-gate-operator-with-webhooks.yaml from a release:
kubectl apply --server-side --force-conflicts -f release-gate-operator-with-webhooks.yamlThis additionally installs:
- Admission webhooks
- Certificate and Issuer resources
- Webhook service configuration
This mode avoids webhooks and cert-manager entirely.
Instead of creating a Deployment directly, you create a ReleaseManagedDeployment.
The operator then creates and reconciles the underlying Deployment for you.
spec.deployment is effectively a DeploymentSpec passthrough.
Everything you would normally put under a Deployment’s .spec goes under:
ReleaseManagedDeployment.spec.deployment
The operator only adds or overrides what it needs for rollout gating and tracking.
apiVersion: platform.ivlabs.online/v1alpha1
kind: ReleaseManagedDeployment
metadata:
name: myapp
spec:
releaseGate:
enabled: true
command: |
echo "Running pre-release step"
sleep 20
echo "Done"
deployment:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: busybox:1.37
command: ["sleep", "3600"]- The image tag changes in
spec.deployment - The operator detects a new desired state
- A blocking Job is created to run the configured command
- The Deployment is applied only after the Job succeeds
- If the Job fails, the rollout is blocked
You can inspect status with:
kubectl get releasemanageddeployments
kubectl describe releasemanageddeployment myappIf you don’t want to introduce a new CRD, the operator can mutate existing Deployments using admission webhooks.
⚠️ This mode requires admission webhooks and cert-manager.
| Annotation | Description |
|---|---|
release-gate/enabled |
Enable release gating |
release-gate/command |
Command executed in the blocking Job |
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
annotations:
release-gate/enabled: "true"
release-gate/command: |
echo "Running pre-release step"
sleep 20
echo "Done"
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: busybox:1.37
command: ["sleep", "3600"]In this mode, the webhook pauses the Deployment until the gate Job completes successfully.
Rollbacks are handled naturally:
- Changing the image tag back triggers a new reconciliation
- The configured gate runs again for that version
The operator:
- Does not enforce migration semantics
- Does not assume forward-only or backward-only changes
- Only guarantees ordering and gating
Release logic remains fully under your control.
- CRD-based mode: recommended
- Webhook-based mode: optional
- API version:
v1alpha1 - Actively evolving
Issues and PRs are welcome.
If you’re adding features, please:
- Keep the CRD schema backward-compatible when possible
- Prefer declarative behavior over flags
- Avoid CI coupling
- Keep the operator focused on orchestration, not business logic
See:
CONTRIBUTING.md (in progress)
Apache 2.0