Private Kubernetes Cluster with Security Enhancements (End-to-End Project)

Project Overview

This project aims to deploy a private Kubernetes cluster with strict security controls, including:

We will be using AWS EKS, Terraform, AWS IAM & OIDC, and Kubernetes security policies to build a secure, production-ready private cluster.

Architecture Diagram

Project Implementation Steps

Step 1: Infrastructure Setup Using Terraform

1.1. Create a VPC with Private Subnets

Define a VPC with private subnets and necessary networking components.

resource "aws_vpc" "eks_vpc" {
  cidr_block = "10.0.0.0/16"
  enable_dns_support = true
  enable_dns_hostnames = true
}

resource "aws_subnet" "private_subnet_1" {
  vpc_id                  = aws_vpc.eks_vpc.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "us-east-1a"
  map_public_ip_on_launch = false
}

resource "aws_subnet" "private_subnet_2" {
  vpc_id                  = aws_vpc.eks_vpc.id
  cidr_block              = "10.0.2.0/24"
  availability_zone       = "us-east-1b"
  map_public_ip_on_launch = false
}

1.2. Create an EKS Cluster in Private Subnets

Use EKS module to deploy a private cluster.

module "eks" {
  source = "terraform-aws-modules/eks/aws"
  cluster_name = "private-eks-cluster"
  cluster_version = "1.27"
  subnet_ids = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id]
  vpc_id = aws_vpc.eks_vpc.id
  enable_irsa = true
  enable_dns_hostnames = true
}

Step 2: Configure OIDC Authentication for Secure Access

Enable OIDC Authentication for Kubernetes user authentication.

resource "aws_iam_openid_connect_provider" "eks_oidc" {
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = ["FINGERPRINT"]
  url = module.eks.cluster_oidc_issuer_url
}

This ensures secure IAM integration for IAM Roles for Service Accounts (IRSA).

Step 3: Enforce Pod Security & Network Policies

3.1. Implement OPA/Gatekeeper for Policy Enforcement

Deploy Open Policy Agent (OPA) Gatekeeper for Kubernetes security policies.

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: deny-privileged-containers
spec:
  crd:
    spec:
      names:
        kind: DenyPrivilegedContainers
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package denyprivileged
        violation[{"msg": "Privileged containers are not allowed"}] {
          input.review.object.spec.containers[_].securityContext.privileged == true
        }

3.2. Implement Network Policies for Isolation

Restrict communication between pods using Kubernetes Network Policies.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-all
  namespace: default
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
  ingress: []
  egress: []

Step 4: Secure Kubernetes API Access

Ensure only trusted users can access the cluster using IAM OIDC.

resource "aws_iam_role" "eks_admin" {
  name = "eks-admin"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = { Federated = aws_iam_openid_connect_provider.eks_oidc.arn }
      Action = "sts:AssumeRoleWithWebIdentity"
      Condition = {
        StringEquals = {
          "${module.eks.cluster_oidc_issuer_url}:sub" = "system:serviceaccount:kube-system:eks-admin"
        }
      }
    }]
  })
}

Step 5: Deploy an Application to Validate Security

Deploy an Nginx application to test security policies.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      securityContext:
        runAsNonRoot: true
      containers:
        - name: nginx
          image: nginx
          securityContext:
            allowPrivilegeEscalation: false
          ports:
            - containerPort: 80

Testing & Validation

  1. Check network policies: kubectl get networkpolicy
  2. Ensure pod security policies are applied: kubectl get psp
  3. Test OIDC authentication: aws eks --region us-east-1 update-kubeconfig --name private-eks-cluster
  4. Deploy an application and verify security restrictions: kubectl apply -f nginx-deployment.yaml

Project Summary