DEV Community

altered
altered

Posted on

i built and deployed a 3-tier app on kubernetes and aws eks

i recently finished building and deploying a 3-tier application, starting locally on minikube and then migrating it to aws eks. this post is about what i built, how it all connects, and a couple of things that tripped me up along the way as a beginner who recently completed the aws certified cloud practitioner (clf-c02) exam and the kubernetes and cloud native associate (kcna) certification.

what i built
a simple 3-tier app with:

  • a frontend — nginx serving an html page
  • a backend — node.js api
  • a database — mongodb

the full picture
browser → aws alb → ingress → frontend pod (nginx) → backend pod (node.js) → database pod (mongodb) → ebs volume (persistent storage)

nothing really fancy, just needed to do some hands on in the cloud.

kubectl get all terminal screenshot showing all three pods running

how it works locally (minikube)
i started on minikube, a tool that runs kubernetes on your local machine. the goal was to understand the concepts before touching any cloud resources.
each tier runs in its own kubernetes deployment, which manages your pods and keeps them running. pods talk to each other through services, which give stable dns names inside the cluster. so instead of hardcoding ip addresses, the backend just calls database-service and kubernetes figures out where that is.
sensitive config like database credentials went into a secret. non-sensitive config like the database hostname went into a configmap. both get injected into pods as environment variables at runtime.
the database needed storage that survives pod restarts, so i attached a persistentvolumeclaim. kubernetes provisions the storage and mounts it inside the database pod.
for traffic routing i set up ingress, a single entry point that routes requests based on url path. / goes to the frontend, /api/* goes to the backend.

ive app screenshot showing

migrating to aws eks
once everything worked locally, i deployed the same app to aws eks — amazon's managed kubernetes service. the manifests are pretty much the same except that a few things change when moving to the cloud.
for example, aws ecr(elastic container registry) replaced cases where i would have built images directly into minikube's docker daemon. on eks(elastic kubernetes service), worker nodes are ec2(elastic compute cloud) instances. so i pushed images to amazon ecr (elastic container registry) and updated my deployments to pull from there.

ecr repositories showing backend and frontend

ec2 instances showing two t3.small worker nodes running

i used ebs(elastic block store) for database storage on aws, as opposed to that on minikube which uses local storage. i updated the storageclass in the initially deployed persistent volume claim from standard to gp2 and installed the ebs csi(container storage interface) driver so kubernetes could provision ebs volumes automatically.
locally i used minikube tunnel to expose the app. on eks, i used the alb(application load balancer). the aws load balancer controller watches the ingress resources and automatically creates a real application load balancer with a public dns address.

oad balancers page showing the ALB active and internet-facing

terminal showing kubectl get ingress with the ALB address, kubectl get pvc showing Bound, kubectl get nodes showing two ready nodes

a couple of things that caught me out
arm64 vs amd64 — my mac uses apple silicon (arm64). when i built docker images locally and pushed to ecr, the eks nodes (which run on intel/amd processors) couldn't run them. the error showed an exec format error. the fix was rebuilding with docker buildx build --platform linux/amd64 to explicitly target the right architecture.
iam permissions — on aws, the elastic block store container storage interface driver and the load balancer controller both need to call aws apis to do their jobs. and without the right permissions attached to them, it would fail. this is solved with irsa (iam roles for service accounts) — a way to give kubernetes pods aws permissions without hardcoding credentials. you link a kubernetes service account to an iam role, and pods using that service account automatically get the right aws access.

IAM roles page showing all the eksctl-created IRSA roles

EKS cluster page showing three-tier-cluster Active

looking to build more interesting projects on the cloud and will talk about my journey here.

Top comments (1)

Collapse
 
harjjotsinghh profile image
Harjot Singh

Solid hands-on project - shipping a 3-tier app on EKS end to end teaches you more about the real cost of "production" than any tutorial, because Kubernetes is where the gap between "it runs locally" and "it runs reliably for users" gets brutally concrete. The honest takeaway most people hit: the app code was the small part; the YAML, the networking, the IAM, the ingress, the "why is my pod CrashLoopBackOff" debugging is the actual work. EKS is a great teacher precisely because it refuses to hide that complexity.

The counterpoint worth holding alongside it: that same complexity is overkill for most solo/early projects - EKS is the right tool when you genuinely need its scale/control, and a heavy tax when you don't. The skill is matching deploy-complexity to actual need. I sit on the "make the simple path trivial" end with Moonshift (a multi-agent pipeline that ships a prompt to a deployed SaaS) - deploy to your own Vercel/GitHub without the k8s tax for projects that don't need it yet, ~$3 a build. Both ends of the spectrum are valid. Great learning project. Did EKS feel worth the complexity for this app, or was it more "learn k8s" than "this app needed k8s"? That honest read is useful for others deciding.