← Back to DevBytes

EKS: Complete Setup and Configuration Guide

What is Amazon EKS?

Amazon Elastic Kubernetes Service (EKS) is a managed Kubernetes platform that simplifies running Kubernetes on AWS without needing to install, operate, and maintain your own Kubernetes control plane. It provides a production-grade, scalable, and highly available Kubernetes environment integrated deeply with AWS services like IAM, VPC, and Load Balancers. EKS is certified as conformant by the CNCF, ensuring compatibility with the standard Kubernetes ecosystem.

Why EKS Matters for Developers

For development teams, EKS eliminates the operational burden of managing the Kubernetes control plane—components like etcd, API server, and scheduler are fully managed across multiple Availability Zones. This lets you focus on building applications, while still leveraging native Kubernetes APIs, community tools, and declarative configurations. Key benefits include:

Prerequisites and Preparation

🚀 Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

Before setting up an EKS cluster, ensure you have the following tools installed and an AWS account configured:

Installing Required Tools

Install eksctl and kubectl on your local machine. Example for macOS via Homebrew:

brew install eksctl kubectl
# Verify installations
eksctl version
kubectl version --client

For Linux or Windows, follow the official docs to download binaries or use package managers.

Step-by-Step EKS Cluster Setup

We will create a cluster using eksctl, the fastest and most developer-friendly method. This provisions the control plane, a managed node group, networking, and IAM resources in one command.

Creating a Basic Cluster

Run the following command to create a cluster named dev-cluster in the us-east-1 region with 2 t3.medium nodes:

eksctl create cluster \
  --name dev-cluster \
  --region us-east-1 \
  --nodegroup-name standard-workers \
  --node-type t3.medium \
  --nodes 2 \
  --nodes-min 1 \
  --nodes-max 4 \
  --managed

This command takes about 10–15 minutes. It creates:

Specifying Advanced Networking (Optional)

To use an existing VPC with private subnets and custom networking, define a cluster config file. Example cluster.yaml:

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: advanced-cluster
  region: us-west-2
  version: "1.28"

vpc:
  id: "vpc-0abc12345def67890"
  subnets:
    private:
      private-one: { id: "subnet-0aaa1111" }
      private-two: { id: "subnet-0bbb2222" }
    public:
      public-one: { id: "subnet-0ccc3333" }

nodeGroups:
  - name: private-workers
    instanceType: t3.medium
    desiredCapacity: 3
    privateNetworking: true
    subnets:
      - private-one
      - private-two

managedNodeGroups:
  - name: managed-ng
    instanceType: t3.large
    desiredCapacity: 2
    subnets:
      - private-one
      - private-two

Create the cluster with:

eksctl create cluster -f cluster.yaml

Configuring kubectl and Cluster Access

Once the cluster is created, verify that your local kubectl context is set correctly:

kubectl config current-context
# Should show something like arn:aws:eks:us-east-1:123456789:cluster/dev-cluster
kubectl cluster-info
kubectl get nodes

If the context is missing, eksctl usually updates it automatically. You can manually update kubeconfig with:

aws eks update-kubeconfig --region us-east-1 --name dev-cluster

Deploying a Sample Application

Let's deploy a simple Nginx web server and expose it via an AWS Load Balancer.

Creating a Deployment and Service

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.23
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80

Apply the manifest:

kubectl apply -f deployment.yaml

Check the service and wait for the external IP (AWS will provision a Classic Load Balancer or Network Load Balancer depending on configuration):

kubectl get svc nginx-service --watch
# Note the EXTERNAL-IP once it appears

Access the application via http://<EXTERNAL-IP>.

Using an Ingress with AWS Load Balancer Controller

For more advanced routing (path-based, host-based), install the AWS Load Balancer Controller and create an Ingress resource. First, add the EKS Helm chart repository:

helm repo add eks https://aws.github.io/eks-charts
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  --set clusterName=dev-cluster \
  --set serviceAccount.create=false \
  --set region=us-east-1 \
  --set vpcId=vpc-xxxxxxxx

Then create an Ingress (requires an existing service):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

Apply and retrieve the ALB address:

kubectl apply -f ingress.yaml
kubectl get ingress nginx-ingress

Managing Worker Nodes

EKS offers both managed node groups (recommended) and self-managed node groups. Managed node groups simplify updates, scaling, and termination handling.

Scaling Nodes

You can scale a managed node group imperatively:

eksctl scale nodegroup --cluster=dev-cluster --name=standard-workers --nodes=4 --nodes-min=2 --nodes-max=6

For declarative scaling, update the node group in your cluster config file and run:

eksctl create nodegroup -f cluster.yaml --update

Using Cluster Autoscaler

For automatic scaling based on pending pods, deploy the Kubernetes Cluster Autoscaler (requires IAM policy for ASG access). Example deployment via Helm:

helm repo add autoscaler https://kubernetes.github.io/autoscaler
helm install cluster-autoscaler autoscaler/cluster-autoscaler \
  --set 'autoDiscovery.clusterName'=dev-cluster \
  --set awsRegion=us-east-1

Then annotate your node groups with the required tags (eksctl handles this automatically for managed node groups).

Networking and Security

VPC and Subnet Design

By default, eksctl creates a dedicated VPC with public and private subnets. For production, design a VPC with private subnets for worker nodes and public subnets only for load balancers. Use security groups to restrict pod-to-pod communication.

Security Groups for Pods

EKS supports assigning security groups directly to pods, enabling fine-grained network rules. Enable the feature by adding the securityGroup field in a pod spec or using the SecurityGroupPolicy CRD with the AWS VPC CNI plugin.

IAM Roles for Service Accounts (IRSA)

Instead of distributing AWS credentials to pods, use IRSA to associate an IAM role with a Kubernetes service account. Steps:

  1. Create an IAM OIDC provider for the cluster (eksctl does this automatically if created via eksctl).
  2. Create an IAM role with a trust policy allowing the service account to assume it.
  3. Annotate the service account with the role ARN.

Example using eksctl to create an IRSA association:

eksctl create iamserviceaccount \
  --cluster=dev-cluster \
  --name=s3-reader \
  --namespace=default \
  --attach-policy-arn=arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
  --approve

Then reference the service account in a pod spec:

apiVersion: v1
kind: Pod
spec:
  serviceAccountName: s3-reader
  containers:
    - name: my-app
      image: my-app-image

The pod will have the permissions of the attached IAM role without static credentials.

Network Policies

Install a network policy engine like Calico to restrict pod communication. Calico can be installed via:

kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/v1.12/calico.yaml

Then define a policy to deny all traffic except what you explicitly allow.

Integrating with AWS Services

EKS shines when combined with other AWS services:

Monitoring and Logging

Enable control plane logging to CloudWatch for audit, API, scheduler, and controller manager logs:

eksctl utils cluster-logging enable --cluster=dev-cluster --types=all

Deploy a Fluent Bit daemonset to collect container logs and send them to CloudWatch:

kubectl apply -f https://raw.githubusercontent.com/aws/aws-for-fluent-bit/main/config/fluent-bit-cluster.yaml

For metrics, install the Prometheus Node Exporter and kube-state-metrics, then visualize with Grafana (deploy via Helm).

Best Practices

Conclusion

Amazon EKS provides a robust, managed foundation for running containerized workloads at scale. By using eksctl and following the configuration patterns outlined here—from cluster creation and worker node management to security hardening and AWS service integration—you can accelerate your Kubernetes adoption while maintaining operational excellence. The key is to treat your cluster as code, automate everything possible, and stay aligned with Kubernetes and AWS best practices. Whether you're deploying a simple web service or a complex microservice mesh, EKS gives you the control and flexibility you need without the burden of managing the control plane.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles