Amazon EKS Security Hardening: Complete Implementation Guide

Amazon EKS (Elastic Kubernetes Service) provides managed Kubernetes clusters, but security remains a shared responsibility. This comprehensive guide covers hardening EKS clusters from network configuration to pod security, ensuring your containerized workloads are protected against modern threats.

EKS security encompasses multiple layers: the control plane managed by AWS, the data plane (worker nodes) you manage, and the workloads running on those nodes. Each layer requires specific security controls and configurations to achieve defense in depth.

EKS Control Plane Security

AWS manages the Kubernetes control plane, including etcd encryption, API server availability, and automatic patching. However, you control access to the API server through endpoint configuration and authentication settings.

resource "aws_eks_cluster" "main" {
  name     = "production-cluster"
  role_arn = aws_iam_role.cluster.arn
  version  = "1.28"

  vpc_config {
    subnet_ids              = var.private_subnet_ids
    endpoint_private_access = true
    endpoint_public_access  = false
    security_group_ids      = [aws_security_group.cluster.id]
  }

  encryption_config {
    provider { key_arn = aws_kms_key.eks.arn }
    resources = ["secrets"]
  }

  enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
}

Node Group Security

resource "aws_eks_node_group" "main" {
  cluster_name    = aws_eks_cluster.main.name
  node_group_name = "production-nodes"
  node_role_arn   = aws_iam_role.node.arn
  subnet_ids      = var.private_subnet_ids
  instance_types  = ["m5.large"]

  launch_template {
    id      = aws_launch_template.nodes.id
    version = aws_launch_template.nodes.latest_version
  }

  scaling_config {
    desired_size = 3
    max_size     = 10
    min_size     = 2
  }
}

resource "aws_launch_template" "nodes" {
  name = "eks-nodes"

  metadata_options {
    http_endpoint               = "enabled"
    http_tokens                 = "required"  # IMDSv2 required
    http_put_response_hop_limit = 1
  }

  block_device_mappings {
    device_name = "/dev/xvda"
    ebs {
      volume_size           = 100
      volume_type           = "gp3"
      encrypted             = true
      kms_key_id           = aws_kms_key.ebs.arn
      delete_on_termination = true
    }
  }
}

IRSA (IAM Roles for Service Accounts)

resource "aws_iam_role" "app_role" {
  name = "eks-app-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = { Federated = aws_iam_openid_connect_provider.eks.arn }
      Action = "sts:AssumeRoleWithWebIdentity"
      Condition = {
        StringEquals = {
          "${replace(aws_iam_openid_connect_provider.eks.url, "https://", "")}:sub" = "system:serviceaccount:production:app-sa"
        }
      }
    }]
  })
}

Pod Security Standards

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

Network Policies with Calico

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Secrets Encryption

resource "aws_kms_key" "eks" {
  description             = "EKS Secret Encryption Key"
  deletion_window_in_days = 30
  enable_key_rotation     = true
}

GuardDuty EKS Protection

resource "aws_guardduty_detector" "main" {
  enable = true
  datasources {
    kubernetes { audit_logs { enable = true } }
  }
}

Best Practices

  • Use private endpoint access only when possible
  • Enable envelope encryption for secrets with KMS
  • Implement IRSA for pod-level IAM permissions
  • Enforce Pod Security Standards at namespace level
  • Deploy network policies with Calico or Cilium
  • Enable GuardDuty EKS protection
  • Use managed node groups with IMDSv2 required
  • Encrypt EBS volumes with customer-managed KMS keys
  • Enable all control plane logging
  • Regularly update cluster and node versions

Conclusion

EKS security requires a layered approach covering the control plane, worker nodes, and workloads. By implementing these best practices, you create a secure foundation for running containerized applications in production.