Kubernetes is one of the most impressive pieces of infrastructure software ever built. It solves genuinely hard problems — container scheduling, self-healing, rolling deployments, service discovery, horizontal scaling — at a level of sophistication that took years to develop.

It is also completely unnecessary for serving a static portfolio website. And I think that distinction is worth writing about, because the instinct in the DevOps world is often to reach for the most powerful tool available rather than the most appropriate one.

What Kubernetes actually costs

When people say Kubernetes is complex, they usually mean the learning curve. That is real but finite. The deeper cost is operational: Kubernetes requires ongoing attention in a way that S3 + CloudFront simply does not.

With Kubernetes, you are responsible for: the control plane (unless managed), node health and capacity, networking (CNI plugins, Ingress controllers), certificate management, pod disruption budgets, resource requests and limits, RBAC, and the upgrade path for both the cluster and every component running on it. None of that work disappears just because you chose a managed service like EKS.

The honest questionFor any infrastructure decision, ask: what problem does this solve that simpler alternatives cannot? If you cannot answer clearly, the simpler alternative is probably correct.

What S3 + CloudFront costs instead

S3 + CloudFront requires essentially zero ongoing operational work for a static site. There are no nodes to patch, no pods to monitor, no control plane to upgrade. The infrastructure provisions once via Terraform and then runs without intervention.

The tradeoff is capability. S3 + CloudFront cannot run server-side logic, cannot manage stateful workloads, cannot do anything a server does. But a static site does not need any of those things, so the tradeoff costs nothing.

S3 + CloudFront
Zero ongoing ops work
Sub-millisecond global delivery
Free tier covers portfolio scale
No servers, no patches, no restarts
Scales to millions of requests automatically
Kubernetes
Ongoing node and cluster maintenance
Full container lifecycle management
Significant compute cost at any scale
Horizontal scaling, self-healing pods
Required for stateful or dynamic workloads

Why Kubernetes is still in this platform

The Kubernetes deployment track exists for a different reason: demonstration. The skills required to design and operate a Kubernetes delivery pipeline — Deployments, Services, Ingress, health probes, Helm packaging, rolling updates — are directly relevant to production workloads at scale. A portfolio that only shows S3 + CloudFront leaves that entire skill set invisible.

By running Kubernetes as a parallel track, the platform demonstrates both: the correct tool for the static hosting problem, and the ability to operate container orchestration when the problem actually requires it.

The design decisionThe Kubernetes track is not over-engineering. It is intentional demonstration of a skill set that would be the primary delivery mechanism in a production microservices environment.

When Kubernetes is the right choice

Kubernetes becomes appropriate when you have workloads that need dynamic scaling, when you are running multiple services that need to communicate with each other, when you need fine-grained resource allocation across a shared compute pool, or when you need zero-downtime deployments for stateful applications.

In other words: microservices, APIs, background workers, databases, event-driven systems. Not static websites.

The most common mistake I see is organisations running Kubernetes for workloads that would be better served by a managed platform — App Runner, Fargate, Cloud Run, or even a simple S3 + CloudFront setup. The operational cost of Kubernetes is justified when the problem demands its capabilities. When it does not, you are paying complexity tax for no return.

The takeaway

Choosing the right tool is a more valuable skill than knowing many tools. The decision to use S3 + CloudFront as the primary path is not a concession — it is the technically correct answer to the problem. The decision to include Kubernetes is also correct, for a different reason entirely.

Good platform engineering is not about using every capability available. It is about matching capability to requirement, and being able to articulate why.

The full Kubernetes implementation is documented on the Kubernetes Platform project page. The CI/CD pipeline that runs both tracks is on the CI/CD Pipeline page.