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.
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
}
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
}
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).
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
}
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: []
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"
}
}
}]
})
}
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
kubectl get networkpolicy
kubectl get psp
aws eks --region us-east-1 update-kubeconfig --name private-eks-cluster
kubectl apply -f nginx-deployment.yaml