Case Studies Best Practices
Reference architectures decay faster than the code they describe. These practices cover how to write one that survives contact with a real team, and how to read someone else's without importing their constraints along with their YAML.
How to Use This List
Read section A before writing any reference architecture, and section D before adopting one.
If you already have a reference doc, use section E as an audit: most rot is detectable in under an hour.
A - Anchor Every Reference in Its Context
State the constraints before the design. Team size, service count, cloud, compliance scope, and SLO. A design without stated constraints is unfalsifiable and therefore unusable.
Annotate the Kubernetes minor and the CNI, always. Scheduler behavior, PSS enforcement versions, and API availability all move between minors. "Kubernetes 1.36.2 on EKS with VPC CNI" is a fact; "Kubernetes" is not.
Pin every version in the artifact, not the prose. Digest-pinned images, chart versions, and CRD bundle versions belong in the manifests themselves so a reader can reproduce the state you tested.
Record what you rejected and why. The rejected options carry more information than the chosen one. "We did not use cluster-per-team because we have two platform engineers" tells a reader exactly when to diverge.
Name the isolation boundary explicitly. Namespace, node pool, cluster, or account. Every other decision in the document follows from where you drew this line.
Give the reference an owner and a review date. An unowned architecture doc is a fossil within two minors.
B - Make the Artifacts Honest
Ship manifests that would actually pass your own admission control. If your reference shows a pod without a security context and your cluster enforces PSS restricted, the reference is fiction.
Include requests, limits, and probes in every example. Omitting them for brevity teaches the wrong lesson, and readers copy examples verbatim regardless of what the prose says.
Never publish a real account ID, digest, or hostname. Use an obviously placeholder value. Someone will paste it.
Show the failure mode next to the happy path. A reference that only shows the working case does not teach anyone to operate the system.
Keep the golden path to five steps or fewer. If you cannot describe how a developer ships code in five steps, you have documented a component inventory, not a platform.
Prefer one complete manifest over five fragments. Fragments hide the interactions, and the interactions are the architecture.
C - Write Migrations as Before/After, Not After
Always show the "before" artifact in full. Readers recognize their own system in the before state, and that is what earns their trust in the after state.
Inventory the debt before you design the target. Annotation counts, root-running images, inline secrets. The inventory command belongs in the doc.
Report the real timeline, including the boring parts. "Eight weeks, six of them annotation parity" is far more useful than a translation table that implies an afternoon.
Document the rollback, and prove you used it. A migration story without a rollback path is a story about luck.
Separate what translates mechanically from what must be redesigned. State, service discovery, and startup ordering are always in the second bucket. Say so early.
Keep the parallel-run cost visible. Two controllers, two load balancers, two bills. Hiding it makes the plan look better and the budget review worse.
D - Read Before You Adopt
Grade your context against theirs first. Smaller team, fewer services, or looser compliance means collapse their boundaries, not copy them.
Read what the reference leaves out. A regulated-environment design that says nothing about developer velocity is telling you something about its priorities, not making a mistake.
Assume every number is context-bound. Their spot percentage, their quota values, and their replica counts came from their traffic shape.
Treat generated manifests as first drafts. Kompose and similar tools emit no probes, no requests, and no security context. Their output looks finished and is not.
Extract the decisions, then re-derive the YAML. If you cannot explain why a field is there, you have copied a liability.
E - Keep References Alive
Replay the reference on every Kubernetes minor upgrade. Apply it to a test cluster and see what breaks. This is the single highest-value practice on this page.
Re-audit on any CNI or ingress-controller change. NetworkPolicy semantics and routing behavior are controller-specific, and the reference silently assumed one.
Diff the doc against production quarterly. Drift between the reference and the cluster means one of them is wrong, and it is usually the doc.
Delete references you no longer run. A stale architecture doc is worse than none, because it carries authority it has not earned.
Track the deprecations that will invalidate it. Ingress today, in-tree volume plugins yesterday. Note the API's trajectory next to its use.
Version the reference alongside the platform repo. If the design lives in the same Git history as the manifests, the PR that changes one prompts the change to the other.
When You Are Done
You should be able to answer five questions about any reference you own: what constraints produced it, where the isolation boundary sits, what the golden path is, what was rejected, and which Kubernetes minor and CNI it was validated against.
If any answer is missing, the reference is not finished - it is a draft with good formatting.
For a reference you are adopting, you should be able to name at least two decisions you are deliberately not copying, and why. If you cannot, you have not read it closely enough.
FAQs
How long should a reference architecture be? Long enough to state constraints, decisions, and rejected options. Most useful ones are under 2,000 words plus manifests.
Should the reference live in the platform repo or a wiki? The repo. Wiki docs drift because nothing forces them to be touched when the manifests change.
How do I stop people from copy-pasting the manifests blind? You mostly cannot, which is why the manifests must be production-correct rather than simplified.
What is the most common failure in a reference architecture? An unstated Kubernetes minor. It makes every behavioral claim unverifiable a year later.
How often should the whole set be reviewed? Every minor upgrade at minimum, which on a standard EKS cadence is roughly three times a year.
Is a case study worth writing if the project failed? Especially then. The rejected-options section of a failed migration is the most valuable document a platform team can produce.
Related
- How to Read a Reference Architecture
- Reference: Multi-Tenant EKS Platform
- Reference: Worker-Heavy Cluster
- Reference: Regulated Environment
- Before/After: Compose to EKS Migration
- Before/After: Ingress to Gateway API
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).