# Kubernetes on AWS: EKS Setup with eksctl

- URL: https://karandeepsingh.ca/posts/kubernetes-eks-setup-eksctl/
- Author: Karandeep Singh
- Published: 2026-06-18
- Series: Kubernetes and Containers
- Tags: kubernetes, eks, aws
- Summary: A practical, zero-to-running guide to AWS EKS with eksctl — install the tools, create a cluster with one command, deploy a workload behind an AWS load balancer, and clean up so you do not get a surprise bill.

A local `kind` cluster is perfect for learning, but eventually you need Kubernetes on real infrastructure. On AWS, the managed option is **EKS** (Elastic Kubernetes Service), and the fastest way to stand one up is **eksctl**. This guide takes you from nothing to a running EKS cluster with a workload exposed to the internet — and, just as important, shows you how to tear it down so it does not quietly drain your account.

EKS removes the hardest part of running Kubernetes: you do not manage or patch the control plane. AWS does. With eksctl on top, a production-shaped cluster is a single command. If you are brand new to the objects you will deploy, skim [Kubernetes fundamentals](https://karandeepsingh.ca/posts/kubernetes-fundamentals-pods-deployments-services/) first, then come back.

![Kubernetes on AWS — EKS setup with eksctl](https://karandeepsingh.ca/images/posts/kubernetes-eks-setup-eksctl-card.jpg)

## Prerequisites

You need three CLI tools and AWS credentials with permission to create EKS, EC2, and CloudFormation resources.

```bash
# AWS CLI — configure credentials first
aws configure
aws sts get-caller-identity        # confirm you are authenticated

# eksctl (macOS / Linux via Homebrew)
brew install eksctl

# kubectl
brew install kubectl
```

**warning:**
EKS is **not** free-tier. The control plane bills per hour, plus the EC2 nodes and any load balancers you create. A small demo cluster costs a few dollars a day. Always run the cleanup step at the end of this guide.

## Create the Cluster with One Command

This is the whole setup. `eksctl` provisions a VPC, the EKS control plane, and a managed node group — all as CloudFormation stacks.

```bash
eksctl create cluster \
  --name demo \
  --region us-east-1 \
  --nodes 2 \
  --node-type t3.medium \
  --managed
```

It takes 15–20 minutes. eksctl streams progress and, when finished, writes the cluster's credentials into your `~/.kube/config` automatically. Verify:

```bash
kubectl get nodes
kubectl get pods -A        # core system pods should be Running
```

```mermaid
graph TD
  A[eksctl create cluster] --> B[CloudFormation]
  B --> C[VPC + Subnets]
  B --> D[EKS Control Plane - managed by AWS]
  B --> E[Managed Node Group]
  E --> F[EC2 Worker Nodes]
  D --> F
  F --> G[Your Pods]
```

## Deploy and Expose a Workload

With nodes ready, deploy an app exactly as you would on any cluster. The only EKS-specific part is the Service type.

```bash
kubectl create deployment web --image=nginx --replicas=2
kubectl expose deployment web --type=LoadBalancer --port=80 --target-port=80
kubectl get svc web -w
```

A Service of type `LoadBalancer` tells the AWS cloud controller to provision an Elastic Load Balancer. After a minute or two, the `EXTERNAL-IP` column shows a public DNS name — open it in a browser and you are hitting pods running on EKS.

**tip:**
For real applications you usually front many Services with a single **Ingress** (one load balancer, host/path routing) using the AWS Load Balancer Controller, instead of one ELB per Service. Start with `LoadBalancer` to learn, then graduate to Ingress.

## Inspect and Operate the Cluster

EKS clusters behave like any other Kubernetes cluster, so your usual workflow applies — every command from the [kubectl cheat sheet](https://karandeepsingh.ca/posts/kubectl-cheat-sheet/) works here.

```bash
kubectl get deploy,svc,pods -o wide
kubectl logs deploy/web
eksctl get cluster                 # eksctl's view of your clusters
eksctl get nodegroup --cluster demo
```

If a pod will not start, the diagnosis is identical to anywhere else — see [how to fix Kubernetes CrashLoopBackOff](https://karandeepsingh.ca/posts/fix-kubernetes-crashloopbackoff/).

## Scaling Nodes

Scaling pods is `kubectl scale`. Scaling the underlying EC2 capacity is an eksctl (or autoscaler) operation:

```bash
eksctl scale nodegroup --cluster demo --name <nodegroup> --nodes 4
```

For production, install the Cluster Autoscaler or Karpenter so node capacity follows demand automatically instead of being set by hand.

**Prefer a declarative cluster config?**
Instead of long command-line flags, eksctl accepts a YAML config file:

```yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: demo
  region: us-east-1
managedNodeGroups:
- name: ng-1
  instanceType: t3.medium
  desiredCapacity: 2
```
Apply it with `eksctl create cluster -f cluster.yaml`. This is the version-controllable, repeatable approach for real environments.

## Clean Up to Avoid a Surprise Bill

This is the step people forget. One command deletes everything eksctl created — control plane, node group, and the load balancer from your Service:

```bash
kubectl delete svc web            # removes the ELB first
eksctl delete cluster --name demo --region us-east-1
```

**warning:**
Delete the `LoadBalancer` Service *before* deleting the cluster. An orphaned ELB created by Kubernetes can survive cluster deletion and keep billing. After cleanup, check the EC2 → Load Balancers console to confirm nothing lingers.

## Common Pitfalls

- **Skipping cleanup.** The number one EKS surprise is a forgotten cluster. Make `eksctl delete cluster` a habit.
- **Insufficient IAM permissions.** eksctl needs broad rights to create CloudFormation, EKS, EC2, and IAM resources. A too-narrow policy fails mid-creation.
- **One ELB per Service.** Fine for demos, expensive at scale — move to Ingress.
- **Region mismatch.** Your `kubectl` context, `eksctl` commands, and AWS CLI must all target the same region.

If you already run CI/CD on AWS, the natural follow-on is wiring a pipeline to EKS — the same idea as the existing walkthrough on [deploying Jenkins on EKS](https://karandeepsingh.ca/posts/deploy-jenkins-eks-tutorial/).

**Question:** Are you running EKS, self-managed Kubernetes, or another managed service like GKE — and what drove the choice?

## References and Further Reading

- Amazon Web Services. [Amazon EKS User Guide](https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html). AWS Documentation.
- Weaveworks & AWS. [eksctl — The official CLI for Amazon EKS](https://eksctl.io/). eksctl Documentation.
- Amazon Web Services. [Getting started with Amazon EKS – eksctl](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html). AWS Documentation.
- Kubernetes Authors. [Service of type LoadBalancer](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer). Kubernetes Documentation.

## Quiz

1. What does eksctl use under the hood to provision AWS resources for your cluster?
   a) Terraform
   b) AWS CloudFormation
   c) Ansible
   d) Raw API calls only
   Answer: b. eksctl generates and applies AWS CloudFormation stacks for the VPC, control plane, and node groups, which is why you can inspect and delete everything as CloudFormation stacks.

2. Roughly how long does an initial EKS cluster creation take with eksctl?
   a) A few seconds
   b) About 1 minute
   c) About 15 to 20 minutes
   d) Several hours
   Answer: c. Provisioning the managed control plane and node group through CloudFormation typically takes 15 to 20 minutes. eksctl streams progress while it waits.

3. Which Service type makes EKS provision an AWS load balancer for your app?
   a) ClusterIP
   b) NodePort
   c) LoadBalancer
   d) ExternalName
   Answer: c. A Service of type LoadBalancer triggers the AWS cloud controller to create an Elastic Load Balancer that routes external traffic to your pods.

4. What is the safest way to avoid surprise charges after an EKS tutorial?
   a) Scale the deployment to zero
   b) Stop the EC2 nodes in the console
   c) Run eksctl delete cluster
   d) Delete the kubeconfig file
   Answer: c. `eksctl delete cluster` tears down every CloudFormation stack it created — control plane, node group, and load balancers — so nothing keeps billing. Stopping nodes or editing kubeconfig leaves paid resources running.


