Blog Release author: Keshav Nandlal Pritani author: Sanjog Kumar Dash

Engineering the Release Bus

How Flow Controller Brings Identity, Immutability, and Observability to Kubernetes Releases

Authors: Keshav Nandlal PritaniSanjog Kumar Dash

If you’ve operated Kubernetes at scale, you already know the phrase “it worked in dev” is rarely about code.

Most of the time, the code is fine. What breaks is everything around it: state, configuration, and the assumptions we silently make as changes move from one environment to another.

A container tag gets bumped in one environment but not the next. Helm values drift because someone “just fixed prod” during an incident. A promotion turns out not to be a promotion at all, but a manual reconstruction of what someone thought was tested earlier.

We ran into this often enough to accept a hard truth:adding more pipeline checks or guardrails wouldn’t fix this. The problem wasn’t discipline — it was identity.

So we stepped back and asked a different question:

What if releases moved through environments the way messages move through a bus — unchanged, traceable, and observable?

That question led to the Flow Controller.

Flow Controller is the Release Bus. It’s a central orchestration layer that carries immutable release artifacts from development to production, without mutation, guesswork, or manual reassembly. What flows on this bus is a release descriptor — a structured, versioned document that captures exactly what we intend to run.

And the reason this works in practice is templates.

The Core Idea: Flow Controller as the Release Bus

In most Kubernetes setups, environments behave like disconnected stops:

  • Dev deploys something
  • Staging deploys something similar
  • Prod deploys hopefully the same thing

There’s no strong identity linking those deployments — just convention and trust.

The Flow Controller changes that model. Instead of treating deployments as isolated events, it introduces a central bus that:

  • understands what a release is
  • assigns it a stable identity (UUID)
  • tracks which environments it has passed through
  • enforces promotion rules and dependencies
  • records every transition as an auditable event

A key point here: the Release Bus does not push directly to Kubernetes. It doesn’t replace ArgoCD, and it doesn’t fight GitOps. Git remains the source of truth. ArgoCD remains the reconciler.

Flow Controller coordinates intent, movement, and visibility — and lets GitOps handle execution.

The System We Designed (and Why)

Once we committed to the bus model, a few requirements became obvious. Each one came from a failure mode we had already seen in production.

1. A single release artifact with identity

Promotions fail when they’re based on reconstructed intent. We needed a release object that could be created once, validated once, and then moved forward unchanged. That object is the release descriptor, stored immutably and identified by a UUID.

2. A safe way to generate releases

Release descriptors are too large and too important to handcraft reliably across product versions, deployment modes, and service combinations. Copy-paste doesn’t scale. Templates solve this by acting as deterministic blueprints.

3. A GitOps-native promotion workflow

We didn’t want to reinvent deployment mechanics. Git is still the desired state. ArgoCD is still the reconciler. Flow Controller orchestrates Git state updates that ArgoCD already watches.

4. A real audit trail

Answering “who deployed what and when” shouldn’t require Git archaeology and Slack searches. Every promotion creates a deployment history record with status, user, timestamps, and progress.

5. Debuggability under stress

When something goes wrong, engineers need to know where it’s stuck: Git update, Argo refresh, sync, or workload health. Promotions are asynchronous, with explicit stepwise progress tracking for exactly this reason.

High-Level Architecture

At a high level, Flow Controller is composed of a small set of services aligned with the release lifecycle:

  • Template Service – stores and resolves versioned templates
  • Release Service – creates immutable releases (UUID + descriptor)
  • Environment Service – manages environment configuration and current releases
  • GitOps Engine – applies descriptor changes into environment Git repositories
  • ArgoCD Integration – refresh, sync, and health polling
  • Deployment History – the audit and debugging timeline for promotions

There’s also a UI built on the same APIs. Everything described here can be done via UI or automation — no hidden paths.

Templates: Where Releases Actually Begin

A release descriptor is the artifact.A template is how you generate that artifact reliably.

Without templates, engineers inevitably start copying old releases, tweaking a few values, and missing something subtle. Templates eliminate that entire class of problems.

A Release Template is a versioned JSON blueprint that defines the shape of a release descriptor. It describes:

  • which services exist
  • how they’re grouped (app / infra / platform)
  • which workload types are expected
  • which container repositories are allowed
  • which values change every release vs remain pinned

Templates support placeholders like <RELEASE_TAG>, which are filled at release creation time.

Example Release Template (Simplified)

{
  "core": {
    "api": {
      "Deployment": {
        "containers": {
          "api": { "repo": "org/api", "tag": "<RELEASE_TAG>" }
        }
      }
    }
  },
  "infra": {
    "gateway": {
      "Deployment": {
        "containers": {
          "gateway": { "repo": "org/gateway", "tag": "stable" }
        }
      }
    }
  }
}

This is where discipline gets encoded into the system:

  • application components move with every release
  • infrastructure stays pinned unless intentionally changed

Templates are resolved using semantic-version fallback (X.Y.Z → X.Y.0 → default), which keeps things flexible without creating template sprawl.

Template Retrieval (API + UI)

Most engineers interact with templates through the UI, but the underlying API is intentionally simple:

GET /v1/releases/template/:productVersion

This returns the resolved template JSON. From there, teams can tweak it in the UI, override specific fields in CI, or submit it directly for release creation.

Creating the Release Descriptor (Template → Artifact)

Release Descriptor

This is where intent becomes an immutable artifact.

POST /v2/releases/create/:productVersion

The request body is a concrete release descriptor, usually generated by resolving a template and filling in placeholders like <RELEASE_TAG>.

Once validated, Flow Controller stores the descriptor and assigns it a UUID:

{
  "releaseId": "b7e6c1e2-2c3a-4e2a-8e2b-1c2d3e4f5a6b",
  "status": "created"
}

From this moment onward:

  • the descriptor is immutable
  • the UUID is the release
  • promotions move identity, not reconstructed config

Promotion Flow: Descriptor → Git → ArgoCD → Cluster

Take a look at the release promotion data flow and user interface given below:

Release Promotion Data Flow
Release Promotion User Interface

Promotion is not “deploy again.” It’s moving the same release identity forward.

POST /v2/releases/:releaseId/promote

Behind the scenes:

  • a deployment history record is created
  • Git values are rendered from the release descriptor
  • commits are pushed
  • ArgoCD refreshes and syncs
  • Flow Controller polls until convergence

Flow Controller never deploys directly to Kubernetes. Git remains the source of truth. ArgoCD remains the reconciler.


Tracking Promotion Status (Incident-Time Gold)

The following image depicts the different environments the release has been promoted to:

Release Details

Every promotion creates a deployment history record that can be queried directly:

GET /v1/environments/staging/deployment-history/421

Instead of “something is broken,” engineers get clarity:

  • where the promotion is
  • what step it’s waiting on
  • whether it’s Git, ArgoCD, or workload health

That difference matters during incidents as represented by the images below:

Deployment Details Depicting Environment and Status Updates
Deployment Details Depicting Application Component Changes
Deployment Details Depicting Application Component Changes (Continued..)

Real-Time Monitoring: Closing the Feedback Loop

Promotion without feedback is just optimism.

Flow Controller continuously polls the ArgoCD API and correlates that data with release UUIDs, environments, and deployment history. This turns raw cluster health into release health.

Engineers can see:

  • Health: Healthy, Progressing, Degraded, Suspended
  • Sync: Synced or OutOfSync

Flow Controller can also inspect live Kubernetes resources and verify that the images running in the cluster match the release descriptor.

That answers the most important production question:

“Is this cluster running exactly what this release defines?”

Why This Actually Stops Drift

Environment drift happens when release identity dissolves over time.

Flow Controller makes that impossible by design:

  • templates define intent
  • descriptors freeze it
  • the Release Bus preserves it
  • GitOps executes it
  • monitoring verifies it
  • history records it

Promotion stops being faith-based and becomes verifiable.

The Shift That Actually Matters

Before Flow Controller:

  • deployments were actions
  • environments were loosely related
  • rollbacks were educated guesses

After Flow Controller:

  • releases are artifacts
  • environments are checkpoints on a bus
  • rollbacks mean selecting a UUID

That conceptual shift removed a huge amount of operational noise.

Conclusion

Every platform that scales eventually learns this lesson:

Velocity without identity is just faster confusion.

The Release Bus gives identity back to releases — not by adding more rules, but by making the right thing the natural thing.

So when someone asks, “What’s running in production — and is it exactly what we tested?”The answer isn’t a Slack thread.It isn’t a Git blame.It isn’t a guess.

It’s a release ID, verified against the cluster.

And that’s when the system finally starts working with you, not against you.

Listen to Acceldata's Kubernetes experts talk here:

All Hands On: Episode 2: Flow Controller : A Solution to Kubernetes Releases | Ashwin Rajeeva ft. Neeraj Nayan