EKS Clusters on Customized VPCs: A Guide for Beginners

Ranjeet Jadhav
5 min readOct 14, 2023
EKS LOGO

Introduction:

Welcome back to the second part of our DevOps automation journey! In this blog, we’ll dive into the world of Kubernetes and explore how to deploy an Amazon EKS cluster within the customized VPC we created using Terraform in the https://medium.com/@devops-blogs/terraform-aws-vpc-93fda88a7b0b blog.

What is Amazon EKS? Before we get started, let’s understand what Amazon EKS is all about. EKS, short for Elastic Kubernetes Service, is AWS’s managed Kubernetes offering. With EKS, you can leave the heavy lifting of managing the Kubernetes control plane and worker nodes to AWS. The result? A fully managed, scalable, and highly available Kubernetes cluster without the hassle of infrastructure management.

Reviving the Customized VPC: To proceed with creating the EKS cluster, it’s essential to have the customized VPC up and running. If you missed our previous blog on how to create a custom VPC using Terraform, now’s the time to take a quick look and set the stage for our EKS adventure.

Now, let’s dive into the exciting part — configuring the EKS cluster using Terraform!

Step 1: Prerequisites: Ensure you have the following prerequisites in place:

  1. Customized VPC from our previous blog https://medium.com/@devops-blogs/terraform-aws-vpc-93fda88a7b0b.
  2. AWS CLI and kubectl installed on your local machine.

Step 2: EKS Configuration with Terraform: In your favorite code editor, create a new file named “eks.tf” in same folder that we have created in the previous blog and paste the following configuration:

#====================== EKS Cluster Configuration ==========================

# IAM Role for EKS Cluster
resource "aws_iam_role" "eks_cluster-terra" {
name = "eks-cluster-terra"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}

# IAM Role Policy Attachments
resource "aws_iam_role_policy_attachment" "AmazonEKSClusterPolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.eks_cluster-terra.name
}

resource "aws_iam_role_policy_attachment" "AmazonEKSServicePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy"
role = aws_iam_role.eks_cluster-terra.name
}

# EKS Cluster Resource
resource "aws_eks_cluster" "aws_eks" {
name = "eks-cluster-terra"
role_arn = aws_iam_role.eks_cluster-terra.arn

vpc_config {
subnet_ids = ["${aws_subnet.private_subnets[0].id}", "${aws_subnet.private_subnets[1].id}", "${aws_subnet.public_subnets[0].id}", "${aws_subnet.public_subnets[1].id}"]
endpoint_private_access = true
endpoint_public_access = true
public_access_cidrs = ["0.0.0.0/0"]
}

tags = {
Name = "eks-terra"
Owner = "Ranjeet Jadhav"
}
}

# IAM Role for EKS Node Group
resource "aws_iam_role" "eks-node-grp-terra" {
name = "eks-nodegrp-terra"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}

# IAM Role Policy Attachments for EKS Node Group
resource "aws_iam_role_policy_attachment" "AmazonEKSWorkerNodePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.eks-node-grp-terra.name
}

resource "aws_iam_role_policy_attachment" "AmazonEKS_CNI_Policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.eks-node-grp-terra.name
}

resource "aws_iam_role_policy_attachment" "AmazonEC2ContainerRegistryReadOnly" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.eks-node-grp-terra.name
}

# EKS Node Group Resource
resource "aws_eks_node_group" "node" {
cluster_name = aws_eks_cluster.aws_eks.name
node_group_name = "eks-node-group-terra"
node_role_arn = aws_iam_role.eks-node-grp-terra.arn
instance_types = ["t2.medium"]
subnet_ids = ["${aws_subnet.private_subnets[0].id}", "${aws_subnet.private_subnets[1].id}"]
ami_type = "AL2_x86_64" # AL2_x86_64, AL2_x86_64_GPU, AL2_ARM_64, CUSTOM
capacity_type = "ON_DEMAND" # ON_DEMAND, SPOT
disk_size = 20

scaling_config {
desired_size = 1
max_size = 1
min_size = 1
}

# Ensure that IAM Role permissions are created before and deleted after EKS Node Group handling.
# Otherwise, EKS will not be able to properly delete EC2 Instances and Elastic Network Interfaces.
depends_on = [
aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy,
aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy,
aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly,
]
}

# ===========================================================================

In the “eks.tf” file, we define the Terraform configuration required to set up an Amazon EKS cluster within the customized VPC that was created in the previous blog. Let’s break down each section of the “eks.tf” file and understand what it does:

  1. IAM Roles for EKS Cluster and Node Group:
  • We create two IAM roles, one for the EKS cluster (aws_iam_role.eks_cluster-terra) and the other for the EKS node group (aws_iam_role.eks-node-grp-terra).
  • The assume_role_policy specifies that these roles are allowed to be assumed by specific AWS services, in this case, eks.amazonaws.com for the EKS cluster role and ec2.amazonaws.com for the EKS node group role.

2. IAM Role Policy Attachments:

  • We attach policies to the IAM roles to grant them specific permissions.
  • The AmazonEKSClusterPolicy and AmazonEKSServicePolicy are attached to the EKS cluster role, allowing it to manage the cluster and interact with other AWS services related to EKS.
  • The AmazonEKSWorkerNodePolicy, AmazonEKS_CNI_Policy, and AmazonEC2ContainerRegistryReadOnly are attached to the EKS node group role, granting necessary permissions for worker nodes to join the cluster, interact with networking, and pull container images from the ECR registry.

3. EKS Cluster Resource:

  • We define the EKS cluster using the aws_eks_cluster resource block.
  • The name attribute specifies the name of the EKS cluster.
  • The role_arn attribute points to the IAM role created earlier for the EKS cluster.
  • The vpc_config block provides details about the VPC settings for the EKS cluster, including the private and public subnets it should use.

4. EKS Node Group Resource:

  • We define the EKS node group using the aws_eks_node_group resource block.
  • The cluster_name attribute links the node group to the EKS cluster created above.
  • The node_group_name attribute sets the name of the node group.
  • The node_role_arn attribute points to the IAM role created earlier for the EKS node group.
  • We specify the instance_types, subnet_ids, ami_type, and capacity_type for the worker nodes.

Step 3: Deploying the EKS Cluster: With the EKS configuration in place, it’s time to deploy the cluster:

Initialize Terraform:

terraform init

Validate the configuration:

terraform validate

Apply the changes and create the cluster

terraform apply

Now that we have successfully created the Amazon EKS cluster within our custom VPC using Terraform, it’s time to connect to the cluster and interact with it.

In your terminal or command prompt, run the following command:

aws eks update-kubeconfig --name eks-cluster-terra

Replace eks-cluster-terra with the name you provided for your EKS cluster in the Terraform configuration.

This command retrieves the access credentials for the cluster and automatically updates your kubeconfig file, which is used by kubectl to communicate with the cluster.

Verify the Connection: To verify that kubectl is correctly configured to communicate with your EKS cluster, run the following command:

kubectl get nodes

Conclusion:

Congratulations! You’ve just embarked on an exciting journey to build an Amazon EKS cluster within your custom VPC using Terraform. By combining the powers of Kubernetes and DevOps automation, you’re now equipped to deploy and manage containerized applications like a pro.

In the upcoming blog, we’ll explore advanced topics like setting up Load Balancers, deploying applications, and auto-scaling with EKS. Stay tuned for more insights into the fascinating world of Kubernetes and the limitless possibilities of DevOps automation.

Start your Kubernetes adventure today and elevate your infrastructure game with Amazon EKS and Terraform. Happy Kuberneting!

--

--