A GitOps controller can render a chart, apply values from another repository, expand a Kustomize base, and substitute an image reference. The final Kubernetes objects depend on all of those inputs. Recording only the application repository commit misses a chart that advanced independently, a values branch that moved, or an image tag that was replaced. A release record should bind the source revision, chart or base revision, renderer version, values revision, image digest, and digest of the rendered object set that the controller actually applied.
GitOps render locks: identify every input behind an applied manifest
Operational decision
A billing-ledger Deployment is assembled from a chart repository, a platform values repository, and an image built by the service team. The release job resolves each reference to an immutable revision, renders the manifests in a clean workspace, validates policy against the rendered output, and records a digest over a canonical resource inventory. It then asks the controller to reconcile those same revisions. Compare the controller's observed source and manifest digest with the candidate, and inspect the running image ID after rollout. During the drill, move a chart tag and a values branch without changing the application commit; the release must detect that the render changed rather than reporting the old release as identical. If the controller supports multiple sources, detect duplicate group-kind-namespace-name tuples before syncing because a later source may replace an earlier resource while still leaving a warning. Do not include live status or server-generated metadata in the canonical digest. Store the renderer version and relevant plugin configuration so a future investigator can reproduce the build even after local tooling is upgraded.
Billing render record
App revision: immutable commit
Chart or base: immutable revision and package digest
Values: immutable revision and chosen file
Renderer: version and plugin set
Image: tested manifest digest
Output: canonical resource-set digest
Cluster: observed source and applied revisionCost and verification
Rendering N objects costs work proportional to their total source and output bytes plus template evaluation; retaining each rendered snapshot adds storage per release. That cost is usually smaller than triaging an unrepeatable deployment. Measure releases with floating inputs, local-versus-controller render mismatches, duplicate resource identities, and running image digests that differ from the accepted candidate. Pinning inputs does not prove the program behaves correctly; it makes the deployed state explainable.
Common Mistakes
- Do not treat one Git commit as the complete release identity when charts or values come from elsewhere.
- Do not hash server-generated status fields as release intent.
- Do not ignore duplicate rendered resource identities.
Connected lessons
- DevOps: delivery, infrastructure, and reliable operations
- GitOps reconciliation: desired state and drift
- Helm release review: render before applying
- Tested artifact identity: deploy the bytes that passed
- SBOM binding: keep the inventory attached to the tested digest
