Command Palette

Search for a command to run...

Hectal
← All projects

Project 8 of 12 · project brief

Run the Stack on Amazon EKS

An EKS cluster built with Terraform, the app deployed with its Helm charts, managed data services, IRSA/Pod Identity, and the AWS Load Balancer Controller.

Advanced 4–5 days 4 milestones

The scenario

The Kubernetes version of ShopLite (Projects 5–6) must now run on AWS. Your brief: a production-ready EKS cluster built entirely with Terraform, stateful services moved to managed AWS offerings where sensible, and the app deployed with the Helm charts, with no static AWS credentials anywhere.

Before you start

Stack

Terraform (terraform-aws-modules/eks)EKS + managed node group / KarpenterEKS Pod IdentityAWS Load Balancer ControllerEBS CSIRDS PostgreSQLElastiCache (Valkey)Amazon MSK or StrimziECRHelm

Target architecture

Project 8 architecturediagram
Rendering diagram…

Deliverables and requirements

You will hand in

  • Terraform for EKS (cluster, node group or Karpenter, add-ons: VPC CNI, CoreDNS, kube-proxy, EBS CSI, Pod Identity agent)
  • Managed RDS, ElastiCache, and MSK (or Strimzi on EKS, with justification)
  • AWS Load Balancer Controller installed; Ingress creates an ALB
  • App deployed via the Helm charts with prod values; images from ECR

Functional

  • App reachable through an ALB created from a Kubernetes Ingress
  • Pods access AWS (S3, Secrets Manager) through Pod Identity, never access keys
  • Cluster recreated from scratch with terraform apply + helm install

Non-functional

  • Private API endpoint or restricted public CIDRs
  • Nodes in private subnets across 3 AZs
  • Cluster access via EKS access entries mapped to IAM roles (no shared kubeconfig)
  • Control plane logs enabled

Milestones

  1. 1

    Cluster with Terraform

    Done when: An EKS cluster with managed add-ons and access entries.

    • Use terraform-aws-modules/eks/aws with the Project 7 VPC
    • Managed node group (2–3 nodes) for system workloads; optionally Karpenter for apps
    • Access entries: admin role for the platform team, view role for developers
    • Enable control plane logging (api, audit, authenticator)

    Prove it works

    terminal
    $ aws eks update-kubeconfig --name shoplite-prod && kubectl get nodes -L topology.kubernetes.io/zone
    ── expected output ──
    NAME STATUS ZONE
    ip-10-20-11-14.ap-south-1... Ready ap-south-1a
    ip-10-20-12-87.ap-south-1... Ready ap-south-1b
    ip-10-20-13-5.ap-south-1... Ready ap-south-1c
  2. 2

    Managed data services

    Done when: RDS, ElastiCache, and MSK reachable only from the cluster.

    • Reuse the Project 7 database module; add ElastiCache and MSK modules
    • Security groups: allow from the EKS node/pod security group only
    • Store endpoints/credentials in Secrets Manager

    Prove it works

    terminal
    $ kubectl run -it --rm pg --image=postgres:17 -- psql "$DB_URL" -c 'select 1'
    ── expected output ──
    ?column?
    ----------
    1
  3. 3

    Controllers and identity

    Done when: AWS Load Balancer Controller and Pod Identity for app service accounts.

    • Install the AWS Load Balancer Controller (Helm) with its IAM role via Pod Identity
    • Pod Identity associations for api (S3 bucket + secret read) and worker
    • Install External Secrets (GitOps course, Mission 2.1) to sync DB credentials

    Prove it works

    terminal
    $ kubectl -n shoplite exec deploy/api -- aws sts get-caller-identity --query Arn --output text
    ── expected output ──
    arn:aws:sts::123456789012:assumed-role/shoplite-api-pod/eks-shoplite-...
  4. 4

    Deploy the app

    Done when: The Helm charts deployed with prod values; ALB serving traffic.

    • Push images to ECR (with Project 2's tagging)
    • values-prod.yaml: external DB/cache/Kafka hosts, Ingress class alb with annotations for scheme and target type ip
    • helm upgrade --install and verify

    Prove it works

    terminal
    $ kubectl -n shoplite get ingress shoplite -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'; echo; curl -s http://$(kubectl -n shoplite get ingress shoplite -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')/api/actuator/health
    ── expected output ──
    k8s-shoplite-shoplite-3f2a1c9b8d-1234567890.ap-south-1.elb.amazonaws.com
    {"status":"UP"}

Would you run this in production?

  • ☐No static AWS keys in the cluster (Pod Identity/IRSA)
  • ☐Least-privilege access entries; audit logs on
  • ☐Nodes private, spread across AZs; PDBs and topology spread
  • ☐Managed data services with backups and Multi-AZ
  • ☐Cluster upgrade plan documented (Advanced Kubernetes guide)

Stretch goals

  • Add Karpenter with Spot (Platform course, Mission 0.3)
  • Use Gateway API instead of Ingress
  • Blue-green cluster upgrade drill

Show it off

Résumé bullet

Built a production EKS platform with Terraform (managed add-ons, access entries, Pod Identity, AWS Load Balancer Controller) and deployed a microservices app using managed RDS, ElastiCache, and MSK, with zero static AWS credentials.

Demo script

  • terraform destroy + apply the app layer to show reproducibility
  • Show a pod's AWS identity via STS
  • Show the ALB created from an Ingress

Interview questions about this project

01

How do pods on EKS get AWS permissions securely?

02

Would you run Kafka and Postgres inside EKS or use managed services?