Release Unit
also called Promotable Set, Deployment Bundle
The complete set of inputs a promotion must move together - artefact digest, configuration revision, flag defaults and schema version - because promoting only the artefact leaves the rest as untested variables.
A team wires up artefact promotion properly: the pipeline builds once, the deploy references a digest rather than a tag, and the runbook says production runs exactly what passed in staging.
Then a release behaves differently in production and the digest turns out to be identical. The chart values were not. Staging had a cache TTL of 60 seconds and production had 3,600, and the defect only appears once entries live past five minutes.
A running service's behaviour is a function of four inputs: the artefact, the configuration it starts with, the schema it reads, and the values its flags evaluate to. Promoting the digest pins one of the four. The release unit is all four, treated as one promotable thing.
Why it matters
Promotion exists to make a claim: this thing was tested, and this same thing is now in production. Pinning one input out of four leaves three free to differ, so the tested configuration and the production configuration are different programs sharing a binary.
The consequence is that a whole class of production defect is unreachable in pre-production and no amount of additional testing finds it, because the test never runs the pair that fails. Teams respond by adding environments, which multiplies the pairs rather than pinning any.
The second consequence is forensic. When a review asks what was running at 14:00, a digest-only record cannot say which values, flag defaults or migration set were in force.
Implementation patterns
- Resolve configuration at build time, not deploy time. Render the environment's values into a named revision during the pipeline and promote the (digest, configuration revision) pair.
- Make the deploy refuse an unknown pair, by verifying that the pair it was handed is the one that passed the preceding stage, so a hand-edited value cannot enter at the last hop.
- Put flag defaults inside the unit. A flag whose default differs between environments is configuration under another name, and the default is what a cold start uses.
- Record the schema version and write the whole pair into the deployment record, so an incident timeline can resolve a timestamp to a complete input set.
Industry example
The rendered-manifest approach used by declarative deployment tooling is the clearest industry expression of this idea. Rather than storing templates and letting the cluster-side tool interpolate at apply time, the pipeline renders the final manifests per environment, commits them, and the reconciler applies bytes it does not transform. The reviewable diff then shows every resolved value in effect and the deploy record is a commit.
Teams that adopt it report the same first discovery: environments believed identical differ in dozens of resolved values nobody had looked at, because templating hid them behind a variable name.
Failure scenarios
- The TTL case: identical digest, different timeout values, and a defect that only appears above one.
- A flag default flipped in production months earlier by someone debugging and never reconciled, so the promoted artefact takes a different code path.
- Promotion crossing a schema boundary: the artefact passed against migration set 41 and production is on 39, so the promotion asserts something that was never true.
- Last-hop edits by a deploy job that templates values from CI environment variables no review covered.
Trade-offs
| Choose | Gains | Pays |
|---|---|---|
| Digest-only promotion | Simple pipeline, one artefact store | Three untested variables, weak deployment record |
| Full release unit | A promotion claim that holds, resolvable incident timeline | Build-time rendering, a second artefact to version and garbage-collect, a deploy that can refuse |
The cost is concentrated in one place: configuration must be resolved earlier, which means an urgent value change now goes through the pipeline rather than through a deploy flag. That is the intended effect and it is also the complaint you will hear.
When not to use it
If the only differences between environments are endpoints and platform-injected secrets, and every behavioural setting is identical, a digest plus a values file committed at the same commit is already the pair. Building a separate bundle artefact buys nothing and costs a stage plus an artefact store to prune.
The test is concrete: list the configuration keys that differ between environments and mark which can change behaviour rather than destination. If that list is empty, stop.
Interview question
Q: "Your pipeline builds once and promotes the image digest from staging to production, and you tell me production runs what was tested. I do not believe you. Convince me, and tell me what you would have to change if you cannot."
What a strong answer covers: naming the four inputs and conceding only one is pinned; the TTL or flag-default example as the concrete failure; resolving configuration at build time into a promotable revision; the deployment record as the forensic payoff; and the limit, that if nothing behavioural differs between environments the simpler setup is already correct.
Quick check
Quiz: A release is promoted by digest and behaves differently in production. The digest matches. Name the three remaining suspects. — Configuration values, flag defaults and the applied schema version.
Flashcard: What is the release unit? — The smallest set of inputs that, held constant, makes behaviour reproducible: digest plus configuration revision plus flag defaults plus schema version.