The goal of this task is to provision an AWS EKS (Elastic Kubernetes Service) cluster using Terraform, integrate IAM roles for service accounts, and deploy a sample application.
aws configure
)terraform -v
)kubectl version
)helm version
)mkdir eks-terraform && cd eks-terraform
Create the following Terraform files:
variable "region" {
default = "us-east-1"
}
variable "cluster_name" {
default = "eks-cluster"
}
variable "vpc_cidr" {
default = "10.0.0.0/16"
}
variable "subnet_cidrs" {
type = list(string)
default = ["10.0.1.0/24", "10.0.2.0/24"]
}
provider "aws" {
region = var.region
}
resource "aws_vpc" "eks_vpc" {
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "eks-vpc"
}
}
resource "aws_subnet" "eks_subnet" {
count = length(var.subnet_cidrs)
vpc_id = aws_vpc.eks_vpc.id
cidr_block = var.subnet_cidrs[count.index]
map_public_ip_on_launch = false
availability_zone = element(["us-east-1a", "us-east-1b"], count.index)
tags = {
Name = "eks-subnet-${count.index}"
}
}
resource "aws_eks_cluster" "eks" {
name = var.cluster_name
role_arn = aws_iam_role.eks_role.arn
vpc_config {
subnet_ids = aws_subnet.eks_subnet[*].id
}
depends_on = [aws_iam_role.eks_role]
}
resource "aws_iam_role" "eks_role" {
name = "eksClusterRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "eks.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "eks_policy" {
role = aws_iam_role.eks_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
}
resource "aws_iam_openid_connect_provider" "eks_oidc" {
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = ["9e99a48a9960b14926bb7f3b02e22da2b0ab7280"]
url = aws_eks_cluster.eks.identity[0].oidc[0].issuer
}
resource "aws_iam_role" "app_role" {
name = "app-service-account-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRoleWithWebIdentity"
Effect = "Allow"
Principal = {
Federated = aws_iam_openid_connect_provider.eks_oidc.arn
}
Condition = {
StringEquals = {
"oidc.eks.us-east-1.amazonaws.com/id/${aws_eks_cluster.eks.identity[0].oidc[0].issuer}:sub" = "system:serviceaccount:default:app-service-account"
}
}
}]
})
}
terraform init
terraform apply -auto-approve
Once applied, Terraform provisions the EKS cluster and IAM roles
aws eks update-kubeconfig --name eks-cluster --region us-east-1
kubectl get nodes
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-app
labels:
app: sample-app
spec:
replicas: 2
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
serviceAccountName: app-service-account
containers:
- name: sample-app
image: nginx
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: sample-app-service
spec:
selector:
app: sample-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
Apply the deployment:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Get the external URL:
kubectl get svc sample-app-service
This project automates AWS EKS cluster creation using Terraform, integrates IAM roles for Kubernetes service accounts, and deploys a sample Nginx application behind a LoadBalancer service.
This setup is a solid foundation for deploying microservices on AWS EKS using Terraform and Helm.