17

Package Kubernetes Workloads with Kustomize

Reuse one workload design while keeping dev, staging, and production differences small, explicit, and reviewable.

Run it in the public monorepo

This course is built around the public Zheta Kubernetes Lab monorepo. The excerpt below is runnable source, not pseudocode.

Source: gitops/apps/forge/overlays/prod/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources: [../../base]
commonAnnotations: { zheta.io/release-state: blocked-unpinned }
configMapGenerator:
  - { name: forge-environment, namespace: zheta-forge, behavior: merge, literals: [ENVIRONMENT=prod] }

Code to reality

Declared intent
Reuse the Forge base while keeping production deliberately blocked until immutable image evidence exists.
Interpreter
Kustomize merges the base and environment data; the release verifier rejects the blocking annotation.
Software effect
Production renders shared manifests but remains an explicitly unauthorized release candidate.
Hardware effect
No production workload capacity should be allocated from this blocked source state.
Observable evidence
The rendered annotation and a failing release verifier prove that absence of digests vetoes deployment.

Start with the people and the result they need

The source tables below remain the detailed contract. Begin with these customer paths:

  • D17-UC-01
    • Person: Platform engineer
    • Job: Render one Zheta Forge service for local, dev, staging, and production
    • Observable result: Each environment shares container, probes, security context, and labels while replicas, domains, and capacity vary explicitly
  • D17-UC-02
    • Person: Release reviewer
    • Job: Reject an overlay that removes a required guardrail
    • Observable result: Unsafe change never reaches GitOps reconciliation and prior rendered digest remains promotable

Turn each customer job into a testable story

Now turn each customer job into a story with a result that an engineer can check:

  • D17-US-01
    • Story: As a platform engineer, I want one base with small overlays, so that an important workload fix applies consistently without erasing environment policy
    • Observable acceptance: Rendered object set, tool versions, source revision, image digest, environment diff, run, and output digest are recorded
  • D17-US-02
    • Story: As a release reviewer, I want rendered policy validation, so that a template cannot hide a privileged workload or missing production limit
    • Observable acceptance: Invalid overlay is denied, exact rendered field is identified, and the last approved render still passes

Add real state and observable proof

Finally trace each story through the system that owns its state and the evidence that proves the outcome:

  • D17-FLOW-01
    • Trigger: Engineer proposes a service packaging change
    • Responsible systems: Kustomize renderer, scripts/verify-platform.sh, release verifier, diff reviewer
    • Authoritative state: Git for source; render evidence for output digest
    • Owned record: PackageRevision
    • Observable evidence: Actor, service, image digest, environment, expected and observed objects, source revision, tool version, timestamp, run, render digest, and diff
    • Failure signal: Blocked cloud overlay, mutable image, nondeterministic render, hidden secret, unexpected object, or broad environment diff
  • D17-FLOW-02
    • Trigger: Reviewer evaluates overlay that removes a memory limit
    • Responsible systems: Policy engine, diff reviewer, promotion controller
    • Authoritative state: Policy repository for guardrails; promotion store for approved render
    • Owned record: EnvironmentOverlay
    • Observable evidence: Denial rule, offending object and field, prior digest, unaffected render digest, environment, time, source revision, and run ID
    • Failure signal: Missing resource limit, mutable tag, privileged pod, absent workload identity, or prior digest changed

The enterprise problem and today’s slice

Enterprise problem: Copying complete Kubernetes manifests for every Zheta Forge service and environment causes security fixes, resource limits, and labels to drift, while an overly clever template can hide what production will run. Whole-course context: The incoming evidence is a service map with explicit contracts and owners; today packages those services for Kubernetes without duplicating their whole desired state. Today’s slice: We use the repository’s actual Kustomize base-and-overlay design under gitops/apps/forge; there is no Forge Helm chart, so rendered Kubernetes objects are the honest review boundary. End-of-day evidence: A render run proves all three application archetypes use the same base, each environment changes only declared policy, blocked cloud overlays fail closed until digest promotion, no secret values appear, and output records source revision, tool version, environment, time, run, and digest. Still unsolved: Infrastructure versus workload state, Terraform, and AWS accounts remain deferred.

Customer use cases

Packaging is valuable only when it prevents environment drift without obscuring customer-impacting differences. These use cases cover reusable deployment and rejected unsafe variance.

Use case IDActorCustomer jobSuccess outcomeDenial or recovery evidence
D17-UC-01Platform engineerRender one Zheta Forge service for local, dev, staging, and productionEach environment shares container, probes, security context, and labels while replicas, domains, and capacity vary explicitlyRendered diff reveals every material variance and contains no plaintext secret
D17-UC-02Release reviewerReject an overlay that removes a required guardrailUnsafe change never reaches GitOps reconciliation and prior rendered digest remains promotableSchema or policy denial names missing limit, probe, identity, or forbidden image tag

Actor-centred user stories

A folder hierarchy is not DRY if reviewers cannot predict the final Kubernetes objects. These stories treat deterministic rendering and policy checks as the product of packaging.

Story IDUse case IDsUser storyObservable acceptance conditions
D17-US-01D17-UC-01As a platform engineer, I want one base with small overlays, so that an important workload fix applies consistently without erasing environment policyRendered object set, tool versions, source revision, image digest, environment diff, run, and output digest are recorded
D17-US-02D17-UC-02As a release reviewer, I want rendered policy validation, so that a template cannot hide a privileged workload or missing production limitInvalid overlay is denied, exact rendered field is identified, and the last approved render still passes

End-to-end product flows

GitOps cannot safely reconcile source fragments it has not rendered exactly as the cluster will see them. The flows produce and validate complete Kubernetes objects before promotion.

Flow IDUse case IDsPathTriggerNumbered stepsTerminal evidence
D17-FLOW-01D17-UC-01HappyEngineer proposes a service packaging change1. Resolve gitops/apps/forge/base. 2. Apply named environment overlay. 3. Render complete objects. 4. Validate schemas and blocked/digest-pinned policy. 5. Diff against approved render. 6. Record output digest.Actor, service, image digest, environment, expected and observed objects, source revision, tool version, timestamp, run, render digest, and diff
D17-FLOW-02D17-UC-02DeniedReviewer evaluates overlay that removes a memory limit1. Render candidate. 2. Policy detects missing limit. 3. Block promotion. 4. Preserve prior approved digest. 5. Render unrelated archetype as positive control.Denial rule, offending object and field, prior digest, unaffected render digest, environment, time, source revision, and run ID

The engineer’s source becomes the full object set that a Kubernetes API would receive. Review happens on that result, not only on template fragments.

System design derived from the flows

Packaging claims must match the repository or learners will run nonexistent commands. Zheta Forge currently uses Kustomize only: one stable base plus explicit local, dev, staging, and production overlays.

Use case IDEntry pointResponsible servicesAuthoritative storeFailure evidence
D17-UC-01Packaging pull requestKustomize renderer, scripts/verify-platform.sh, release verifier, diff reviewerGit for source; render evidence for output digestBlocked cloud overlay, mutable image, nondeterministic render, hidden secret, unexpected object, or broad environment diff
D17-UC-02Render policy gatePolicy engine, diff reviewer, promotion controllerPolicy repository for guardrails; promotion store for approved renderMissing resource limit, mutable tag, privileged pod, absent workload identity, or prior digest changed

Git and the GitOps controller own rendered workload declarations; Terraform must not also declare these Deployments. gitops/apps/forge/base is the DRY invariant, each overlay has the SRP of environment variance, and rendering injects that variance without changing service MVC/DI/PubSub boundaries.

Data model and ownership

Rendered YAML is build output, but losing its provenance makes production impossible to reconstruct. Durable evidence binds source, toolchain, environment, and output digest without duplicating ownership of live Kubernetes state.

Generated-application database: Not created in this slice — packaging produces workload declarations and evidence; generated-app domain databases are consumed by services but not created or owned by the renderer.

Record or entityStore and ownerPrimary keyForeign key or opaque referenceTenant keyMaterial constraintLifecycle and deletionUse case IDs
PackageRevisionGit repository, owned by Platform Engineeringcommit_sha plus package_pathOpaque chart and base version refsNone — reusable package has no customer tenantDependencies and image references are pinned; secret values are forbiddenPropose, review, merge, deprecate, retain in Git historyD17-UC-01, D17-UC-02
EnvironmentOverlayGit repository, owned by Environment Ownercommit_sha plus overlay_pathPackageRevision path referenceenvironment_idOverlay may change only allowlisted environment fieldsCreate per environment, review independently, supersede, retain historyD17-UC-01, D17-UC-02
RenderEvidenceEvidence store, owned by Delivery Platformrender_digestOpaque package revision, overlay, toolchain, and policy refsenvironment_idSame immutable inputs must produce same object digestGenerate, approve or deny, promote approved digest, retain through audit windowD17-UC-01, D17-UC-02

The rendered policy result advances to approval or denial, and the evidence preserves the exact output digest. This lets promotion reuse identical bytes while each environment retains its own policy boundary.

Render before reconciliation

Source fragments do not reveal their combined effect, so render and inspect the complete object set. Run this labelled snippet from the public monorepo; the base is gitops/apps/forge/base, overlays are under gitops/apps/forge/overlays, and scripts/verify-platform.sh is the current aggregate gate.

kubectl kustomize gitops/apps/forge/base > /tmp/forge-base.yaml
kubectl kustomize gitops/apps/forge/overlays/local > /tmp/forge-local.yaml
./scripts/verify-platform.sh
./scripts/verify-release.sh staging   # Fails closed until real ECR digests and required Secrets exist.
Effect fieldWhat happens
Declared intentRender the actual Forge base/local overlay and require staging to be digest-pinned before release
Interpreterkubectl kustomize, repository verification scripts, and the named cluster API used by verify-release.sh
Software effectNo live workload changes during render and server dry run; evidence files and policy results are created
Hardware effectLocal or CI CPU, memory, disk, and network serve rendering and validation only
EvidenceFull object YAML, server validation, policy result, diff, source revision, and render digest

Key takeaways

Package once, overlay only real environment differences, and review the rendered objects.

  • Helm packages reusable components; Kustomize composes bases and overlays.
  • DRY means one authoritative invariant, not one environment with hidden switches.
  • GitOps owns workloads only after deterministic rendering and policy approval.

Checklist

Packaging is ready when production output is predictable before reconciliation.

  • [ ] Chart, image, and tool versions are pinned
  • [ ] Overlay changes only allowlisted environment fields
  • [ ] Render contains no plaintext secrets or mutable tags
  • [ ] Invalid overlay and unaffected positive control are recorded