home / skills / itsmostafa / aws-agent-skills / eks

eks skill

/skills/eks

This skill helps you manage AWS EKS clusters, node groups, IRSA, and add-ons, enabling deployment and integration with AWS services.

npx playbooks add skill itsmostafa/aws-agent-skills --skill eks

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
9.4 KB
---
name: eks
description: AWS EKS Kubernetes management for clusters, node groups, and workloads. Use when creating clusters, configuring IRSA, managing node groups, deploying applications, or integrating with AWS services.
last_updated: "2026-01-07"
doc_source: https://docs.aws.amazon.com/eks/latest/userguide/
---

# AWS EKS

Amazon Elastic Kubernetes Service (EKS) runs Kubernetes without installing and operating your own control plane. EKS manages the control plane and integrates with AWS services.

## Table of Contents

- [Core Concepts](#core-concepts)
- [Common Patterns](#common-patterns)
- [CLI Reference](#cli-reference)
- [Best Practices](#best-practices)
- [Troubleshooting](#troubleshooting)
- [References](#references)

## Core Concepts

### Control Plane

Managed by AWS. Runs Kubernetes API server, etcd, and controllers across multiple AZs.

### Node Groups

| Type | Description |
|------|-------------|
| **Managed** | AWS manages provisioning, updates |
| **Self-managed** | You manage EC2 instances |
| **Fargate** | Serverless, per-pod compute |

### IRSA (IAM Roles for Service Accounts)

Associates Kubernetes service accounts with IAM roles for fine-grained AWS permissions.

### Add-ons

Operational software: CoreDNS, kube-proxy, VPC CNI, EBS CSI driver.

## Common Patterns

### Create a Cluster

**AWS CLI:**

```bash
# Create cluster role
aws iam create-role \
  --role-name eks-cluster-role \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "eks.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

aws iam attach-role-policy \
  --role-name eks-cluster-role \
  --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy

# Create cluster
aws eks create-cluster \
  --name my-cluster \
  --role-arn arn:aws:iam::123456789012:role/eks-cluster-role \
  --resources-vpc-config subnetIds=subnet-12345678,subnet-87654321,securityGroupIds=sg-12345678

# Wait for cluster
aws eks wait cluster-active --name my-cluster

# Update kubeconfig
aws eks update-kubeconfig --name my-cluster --region us-east-1
```

**eksctl (Recommended):**

```bash
# Create cluster with managed node group
eksctl create cluster \
  --name my-cluster \
  --region us-east-1 \
  --version 1.29 \
  --nodegroup-name standard-workers \
  --node-type t3.medium \
  --nodes 3 \
  --nodes-min 1 \
  --nodes-max 5 \
  --managed
```

### Add Managed Node Group

```bash
# Create node role
aws iam create-role \
  --role-name eks-node-role \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
aws iam attach-role-policy --role-name eks-node-role --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy

# Create node group
aws eks create-nodegroup \
  --cluster-name my-cluster \
  --nodegroup-name standard-workers \
  --node-role arn:aws:iam::123456789012:role/eks-node-role \
  --subnets subnet-12345678 subnet-87654321 \
  --instance-types t3.medium \
  --scaling-config minSize=1,maxSize=5,desiredSize=3 \
  --ami-type AL2_x86_64
```

### Configure IRSA

```bash
# Enable OIDC provider
eksctl utils associate-iam-oidc-provider \
  --cluster my-cluster \
  --approve

# Create IAM role for service account
eksctl create iamserviceaccount \
  --cluster my-cluster \
  --namespace default \
  --name my-app-sa \
  --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
  --approve
```

**Manual IRSA setup:**

```bash
# Get OIDC issuer
OIDC_ISSUER=$(aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text)
OIDC_ID=${OIDC_ISSUER##*/}

# Create trust policy
cat > trust-policy.json << EOF
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}:sub": "system:serviceaccount:default:my-app-sa",
        "oidc.eks.us-east-1.amazonaws.com/id/${OIDC_ID}:aud": "sts.amazonaws.com"
      }
    }
  }]
}
EOF

aws iam create-role --role-name my-app-role --assume-role-policy-document file://trust-policy.json
```

### Kubernetes Service Account

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app-sa
  namespace: default
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-role
```

### Install Add-ons

```bash
# CoreDNS
aws eks create-addon \
  --cluster-name my-cluster \
  --addon-name coredns \
  --addon-version v1.11.1-eksbuild.4

# VPC CNI
aws eks create-addon \
  --cluster-name my-cluster \
  --addon-name vpc-cni \
  --addon-version v1.16.0-eksbuild.1

# kube-proxy
aws eks create-addon \
  --cluster-name my-cluster \
  --addon-name kube-proxy \
  --addon-version v1.29.0-eksbuild.1

# EBS CSI Driver
aws eks create-addon \
  --cluster-name my-cluster \
  --addon-name aws-ebs-csi-driver \
  --addon-version v1.27.0-eksbuild.1 \
  --service-account-role-arn arn:aws:iam::123456789012:role/ebs-csi-role
```

### Deploy Application

```yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      serviceAccountName: my-app-sa
      containers:
      - name: app
        image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: my-app
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: my-app
```

## CLI Reference

### Cluster Management

| Command | Description |
|---------|-------------|
| `aws eks create-cluster` | Create cluster |
| `aws eks describe-cluster` | Get cluster details |
| `aws eks update-cluster-config` | Update cluster settings |
| `aws eks delete-cluster` | Delete cluster |
| `aws eks update-kubeconfig` | Configure kubectl |

### Node Groups

| Command | Description |
|---------|-------------|
| `aws eks create-nodegroup` | Create node group |
| `aws eks describe-nodegroup` | Get node group details |
| `aws eks update-nodegroup-config` | Update node group |
| `aws eks delete-nodegroup` | Delete node group |

### Add-ons

| Command | Description |
|---------|-------------|
| `aws eks create-addon` | Install add-on |
| `aws eks describe-addon` | Get add-on details |
| `aws eks update-addon` | Update add-on |
| `aws eks delete-addon` | Remove add-on |

## Best Practices

### Security

- **Use IRSA** for pod-level AWS permissions
- **Enable cluster encryption** with KMS
- **Use private endpoint** for API server
- **Enable audit logging** to CloudWatch
- **Use security groups for pods**
- **Implement network policies**

```bash
# Enable secrets encryption
aws eks create-cluster \
  --name my-cluster \
  --encryption-config '[{
    "provider": {"keyArn": "arn:aws:kms:us-east-1:123456789012:key/..."},
    "resources": ["secrets"]
  }]' \
  ...
```

### High Availability

- **Deploy across multiple AZs**
- **Use managed node groups**
- **Set pod disruption budgets**
- **Configure horizontal pod autoscaling**

### Cost Optimization

- **Use Spot instances** for non-critical workloads
- **Right-size nodes and pods**
- **Use Fargate** for variable workloads
- **Implement cluster autoscaler**
- **Use Karpenter** for efficient scaling

## Troubleshooting

### Cannot Connect to Cluster

```bash
# Verify kubeconfig
aws eks update-kubeconfig --name my-cluster --region us-east-1

# Check IAM identity
aws sts get-caller-identity

# Verify cluster status
aws eks describe-cluster --name my-cluster --query 'cluster.status'
```

### Nodes Not Joining

**Check:**
- Node IAM role has required policies
- Security groups allow node-to-control-plane communication
- Nodes have network access to API server

```bash
# Check node status
kubectl get nodes

# Check aws-auth ConfigMap
kubectl describe configmap aws-auth -n kube-system

# Check node logs (SSH to node)
journalctl -u kubelet
```

### Pod Cannot Access AWS Services

```bash
# Verify IRSA setup
kubectl describe sa my-app-sa

# Check pod environment
kubectl exec my-pod -- env | grep AWS

# Test credentials
kubectl exec my-pod -- aws sts get-caller-identity
```

### DNS Issues

```bash
# Check CoreDNS pods
kubectl get pods -n kube-system -l k8s-app=kube-dns

# Test DNS resolution
kubectl run test --image=busybox:1.28 --rm -it -- nslookup kubernetes

# Check CoreDNS logs
kubectl logs -n kube-system -l k8s-app=kube-dns
```

## References

- [EKS User Guide](https://docs.aws.amazon.com/eks/latest/userguide/)
- [EKS API Reference](https://docs.aws.amazon.com/eks/latest/APIReference/)
- [EKS CLI Reference](https://docs.aws.amazon.com/cli/latest/reference/eks/)
- [eksctl](https://eksctl.io/)
- [EKS Best Practices Guide](https://aws.github.io/aws-eks-best-practices/)

Overview

This skill provides AWS EKS Kubernetes management for clusters, node groups, and workloads. It helps create and configure EKS clusters, manage node groups (managed, self-managed, Fargate), set up IRSA, install add-ons, and deploy applications. Use it to integrate Kubernetes workloads with AWS IAM, networking, and storage best practices.

How this skill works

The skill issues AWS CLI and eksctl commands and generates Kubernetes manifests to create clusters, node groups, service accounts, and add-ons. It automates IRSA by associating the OIDC provider and creating IAM roles for service accounts, and it can produce kubeconfig updates and deployment/service YAML for app rollout. It inspects cluster and node status, add-on state, and common failure points to guide troubleshooting.

When to use it

  • Creating a new EKS cluster with recommended defaults (eksctl)
  • Adding or updating managed or self-managed node groups
  • Configuring IRSA for pod-level AWS permissions
  • Installing or updating EKS add-ons (CoreDNS, VPC CNI, EBS CSI, kube-proxy)
  • Deploying Kubernetes applications with load balancer services
  • Troubleshooting connectivity, node join issues, or pod AWS access

Best practices

  • Prefer eksctl for simple, repeatable cluster creation and managed node groups
  • Use IRSA for least-privilege AWS access from pods instead of node IAM roles
  • Enable secrets encryption with KMS and enable audit logging to CloudWatch
  • Deploy across multiple AZs and use pod disruption budgets for availability
  • Use Spot instances or Fargate for cost-sensitive workloads and autoscaling for right-sizing

Example use cases

  • Create a production-ready EKS cluster with managed node groups and KMS secrets encryption
  • Add an autoscaling managed node group with Spot capacity for batch workloads
  • Configure IRSA and a Kubernetes service account for an app that reads from S3
  • Install the EBS CSI driver and deploy a stateful application using persistent volumes
  • Troubleshoot nodes not joining and fix aws-auth or node IAM role issues

FAQ

How do I enable IRSA for a cluster?

Associate the cluster OIDC provider (eksctl utils associate-iam-oidc-provider) then create an IAM role with a trust policy for the service account and annotate the Kubernetes service account with the role ARN.

Which node group type should I use?

Use managed node groups for operational simplicity, self-managed for full control, and Fargate for serverless per-pod compute; consider Spot instances for non-critical workloads.