This project is provided as sample code accompanying the AWS Prescriptive Guidance pattern EKS Cost Optimization: Scaling, Sizing, and Savings. It is not intended for production use without additional security hardening. See "Production Hardening Recommendations" below.
The architecture diagram for this sample lives in the published APG pattern, not in this repository.
If you discover a security vulnerability in this project, please report it by emailing aws-security@amazon.com. Do not report security vulnerabilities through public GitHub issues.
- Amazon EKS — managed Kubernetes control plane where all cost optimization strategies are applied.
- Karpenter — node provisioning controller that manages EC2 instance lifecycle, consolidation, and Spot/On-Demand selection.
- Amazon EC2 — compute instances (including Graviton and Spot) provisioned by Karpenter or Cluster Autoscaler.
- Amazon CloudWatch — metrics collection, Container Insights, and alerting for cluster monitoring and idle detection.
- AWS Identity and Access Management (IAM) — Karpenter node role, IRSA (IAM Roles for Service Accounts), and cluster access policies.
- Amazon ECR — container image registry for multi-architecture (amd64/arm64) images used in Graviton migration.
| Dependency | Where | Notes |
|---|---|---|
karpenter |
Cluster node provisioning | Open-source node provisioner. Confirm the version pinned matches your EKS version compatibility matrix. |
cluster-autoscaler |
Legacy node scaling (if not using Karpenter) | Kubernetes SIG project. Use the version matching your Kubernetes minor version. |
metrics-server |
HPA/VPA resource metrics | Required for Horizontal and Vertical Pod Autoscaler. |
vertical-pod-autoscaler |
Pod right-sizing | Kubernetes community project. Use updateMode: "Off" in production until recommendations are validated. |
keda |
Event-driven autoscaling | Optional. Used for scale-to-zero patterns on intermittent workloads. |
descheduler |
Pod rebalancing | Optional. Used for ongoing bin-packing optimization. |
To deploy this solution, you need:
- An AWS account with permissions to create and manage Amazon EKS clusters, EC2 instances, IAM roles, and CloudWatch resources.
kubectlconfigured with cluster access (aws eks update-kubeconfig --name <cluster>).- AWS CLI v2 configured (
aws configure). - Helm 3.x for installing Karpenter, VPA, and other Kubernetes add-ons.
- Karpenter requires an IAM role with permissions for EC2 instance management — see the Karpenter Getting Started guide.
- The least-privilege IAM policies for Karpenter node role should restrict instance families, Spot usage, and subnet/security group access.
| Consideration | Risk | Mitigation |
|---|---|---|
| Karpenter IAM role permissions | Over-permissive node role can launch any instance type or access unintended resources | Scope IAM policy to specific instance families, subnets, and security groups. Use ec2:RunInstances condition keys. |
| Spot instance interruption | 2-minute termination notice may not allow graceful shutdown of sensitive workloads | Use terminationGracePeriod and Pod Disruption Budgets (PDBs). Keep stateful/sensitive workloads on On-Demand. |
| Multi-architecture images | ARM64 images from untrusted registries may contain vulnerabilities | Pull only from trusted registries (Amazon ECR, verified Docker Hub). Scan images with Amazon ECR image scanning or Amazon Inspector. |
| NodePool resource limits | Missing limits in NodePool spec allows unbounded scaling (cost and security risk) |
Always set cpu and memory limits on every NodePool. |
| Tainted nodes with no workloads | Idle tainted nodes still have kubelet running and are accessible on the VPC network | Audit tainted nodes regularly. Remove unused taints or decommission nodes with zero pods. |
| Cluster Autoscaler ConfigMap exposure | cluster-autoscaler-status ConfigMap may reveal scaling decisions |
Restrict RBAC access to kube-system ConfigMaps. |
| Extended support clusters | Older Kubernetes versions may have unpatched CVEs | Upgrade clusters to standard support versions within 60 days of new release. |
- Restrict Karpenter IAM permissions — Use condition keys (
ec2:InstanceType,ec2:Subnet,ec2:SecurityGroup) to limit what Karpenter can launch. - Enable Pod Security Standards — Enforce
restrictedorbaselinePod Security Standards at namespace level. - Network policies — Apply Kubernetes NetworkPolicies to restrict pod-to-pod communication.
- Image scanning — Enable Amazon ECR image scanning and block deployment of images with critical/high CVEs.
- Audit logging — Enable EKS control plane audit logging to CloudWatch for all API server activity.
- Encrypt secrets — Use AWS KMS envelope encryption for Kubernetes secrets (
aws eks create-cluster --encryption-config). - Node isolation — Use separate NodePools with security groups to isolate sensitive workloads at the network level.
- Regular upgrades — Maintain EKS clusters on standard support to receive security patches and avoid extended support charges.
- RBAC least privilege — Restrict
kubectlaccess using aws-auth ConfigMap or EKS access entries with minimal permissions. - Spot interruption handling — Deploy the AWS Node Termination Handler or rely on Karpenter's built-in interruption handling to gracefully drain nodes before termination.