Create AWS EKS Cluster with VPC using Terraform

VAIBHAV HARIRAMANI
18 min readJun 15, 2024

--

In this tutorial, we will walk through the process of setting up an Amazon EKS (Elastic Kubernetes Service) cluster with a VPC (Virtual Private Cloud) using Terraform. We will cover the following steps:

  1. Install AWS CLI
  2. Connect Terraform with AWS
  3. Set up Terraform modules
  4. Initialize Terraform

By the end of this guide, you will have a running EKS cluster ready for deploying Kubernetes applications.

Prerequisites

Before we begin, ensure you have the following:

  • An AWS account
  • Terraform installed on your machine
  • AWS CLI installed and configured
  • Basic understanding of Kubernetes and Terraform

Step 1: Install AWS CLI

The AWS CLI (Command Line Interface) is a unified tool to manage your AWS services. To install the AWS CLI, follow these steps:

For macOS:

brew install awscli

For Windows:

  1. Download the AWS CLI MSI installer from the AWS CLI MSI installer for Windows.
  2. Run the downloaded MSI installer and follow the on-screen instructions.

For Linux:

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

After installation, verify by running:

aws --version

Step 2: Connect Terraform with AWS

Terraform uses AWS credentials to provision resources. We need to configure the AWS CLI with our credentials.

get your AWS Access Key ID and AWS Secret Access Key:

  1. Sign in to the AWS Management Console:
  • Go to the AWS Management Console.
  • Log in with your AWS account credentials.
  • Navigate to the Security Credentials:
  • scroll down and create new access key
you can create access key from here

OR

  • In the AWS Management Console, search for “IAM” in the search bar and select “IAM” (Identity and Access Management).

Create a New User:

  • In the IAM dashboard, click on “Users” in the left-hand menu.
  • Click the “Add user” button.

Configure User Details:

  • Enter a user name for the new user.
  • Select the “Programmatic access” checkbox to provide access via the AWS CLI, SDK, etc.

Set Permissions:

  • Click “Next: Permissions” to set permissions for the new user.
  • You can either add the user to an existing group with the necessary permissions, copy permissions from another user, or attach policies directly. For basic access, you might attach the “AmazonS3FullAccess” policy or similar.

Review and Create User:

  • Click “Next: Tags” if you want to add any tags, then “Next: Review.”
  • Review the user details and click “Create user.”

Download Credentials:

  • After the user is created, you will see the “Success” page.
  • You will be provided with the Access Key ID and Secret Access Key.

Store Your Keys Securely:

  • Save the Access Key ID and Secret Access Key in a secure location. Do not share them publicly or commit them to version control systems.

You now have your AWS Access Key ID and Secret Access Key, which you can use to access AWS services programmatically.

Run the following command and enter your AWS Access Key ID and Secret Access Key:

aws configure

The output will prompt you to enter:

  • AWS Access Key ID
  • AWS Secret Access Key
  • Default region name (e.g., us-west-2)
  • Default output format (e.g., json)

Step 3: Setting Up Terraform Modules

Create a new directory for your Terraform configuration files.

Inside this directory, create a file named variables.tf. This file will contain the Terraform code for maintaing variables .

variables.tf:

variable "aws_region" {
default = "us-west-1"
description = "aws region"
}

variable "vpc_cidr" {
default = "10.0.0.0/16"
description = "default CIDR range of the VPC"
}

variable "kubernetes_version" {
default = 1.27
description = "kubernetes version"
}

Inside this directory, create a file named vpc.tf. This file will contain the Terraform code for provisioning the VPC.

vpc.tf:


provider "aws" {
region = var.aws_region
}

data "aws_availability_zones" "available" {}

resource "random_string" "suffix" {
length = 8
special = false
}

locals {
cluster_name = "demo-eks-${random_string.suffix.result}"
}

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.7.0"

name = "demo-eks-vpc"
cidr = var.vpc_cidr
azs = data.aws_availability_zones.available.names
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.4.0/24", "10.0.5.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
enable_dns_hostnames = true
enable_dns_support = true

tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
}

public_subnet_tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/elb" = "1"
}

private_subnet_tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
}
}

we will create a Virtual Private Cloud (VPC) in AWS using Terraform. We will go through each part of the Terraform script, explaining its purpose and usage.

1. Provider Configuration

First, we define the AWS provider, which tells Terraform to use AWS for provisioning resources.

provider "aws" {
region = var.aws_region
}
  • provider “aws”: Specifies the AWS provider.
  • region: Sets the AWS region, using a variable var.aws_region. This allows for flexibility to specify different regions without changing the code.

2. Data Source for Availability Zones

We fetch the list of available availability zones in the specified region.

data "aws_availability_zones" "available" {}
  • data “aws_availability_zones” “available”: Defines a data source to get information about available availability zones. This will be used to create subnets in multiple zones for high availability.

3. Local Variables

We define a local variable for the cluster name. Local variables help manage repetitive strings and improve readability.

locals {
cluster_name = "demo-eks-${random_string.suffix.result}"
}
  • locals: Declares local variables.
  • cluster_name: Combines a fixed string with a randomly generated suffix to ensure uniqueness.

4. Random String Resource

A random string is generated to ensure unique resource names.

resource "random_string" "suffix" {
length = 8
special = false
}
  • resource “random_string” “suffix”: Creates a random string resource.
  • length: Specifies the length of the random string.
  • special: When set to false, ensures no special characters are included in the string.

5. VPC Module

We use a VPC module from the Terraform Registry to create the VPC and related resources.

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.7.0"

name = "demo-eks-vpc"
cidr = var.vpc_cidr
azs = data.aws_availability_zones.available.names
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.4.0/24", "10.0.5.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
enable_dns_hostnames = true
enable_dns_support = true

tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
}

public_subnet_tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/elb" = "1"
}

private_subnet_tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
}
}
  • module “vpc”: Declares a module block to use the VPC module from the Terraform Registry.
  • source: Specifies the source of the module (terraform-aws-modules/vpc/aws).
  • version: Defines the version of the module to ensure compatibility and stability.

Module Parameters:

  • name: Names the VPC ("demo-eks-vpc").
  • cidr: Defines the CIDR block for the VPC, using a variable var.vpc_cidr.

Understanding CIDR and Its Use in Setting Up a VPC

What is CIDR?

Classless Inter-Domain Routing (CIDR) is a method for allocating IP addresses and IP routing. Unlike the older classful network design, CIDR allows for more flexible and efficient use of IP address space.

A CIDR notation consists of an IP address followed by a slash (/) and a number that indicates the length of the subnet mask. For example, 192.168.1.0/24 specifies an IP address range that includes all addresses from 192.168.1.0 to 192.168.1.255.

  • IP Address: A unique identifier for a device on a network (e.g., 192.168.1.0).
  • Subnet Mask: Defines the size of the network (e.g., /24 means the first 24 bits are the network part of the address, leaving the remaining bits for host addresses).

Uses of CIDR in Setting Up a VPC

In the context of AWS and setting up a Virtual Private Cloud (VPC), CIDR notation is crucial for defining the IP address range and segmentation within your VPC. Here’s how it’s used:

  1. Defining the VPC IP Range: When creating a VPC, you specify a primary CIDR block. This defines the range of private IP addresses available for resources within the VPC. For example, 10.0.0.0/16 provides a large address space that includes IPs from 10.0.0.0 to 10.0.255.255.
resource "aws_vpc" "main" {   cidr_block = "10.0.0.0/16"   ... }

2. Creating Subnets: Within the VPC, you can create subnets by specifying smaller CIDR blocks that divide the VPC’s IP address space into smaller segments. This helps in organizing and securing resources. For example, creating a public subnet with 10.0.1.0/24 and a private subnet with 10.0.2.0/24.

resource "aws_subnet" "public" {   
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
...
}
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
... }

3. Network Segmentation: Using CIDR blocks, you can segment your network for different purposes, such as public-facing services, internal applications, databases, etc. This enhances security by isolating resources and controlling traffic flow between them.

4. Efficient IP Address Management: CIDR allows efficient allocation and use of IP address space, avoiding the wastage of addresses. For example, a 10.0.0.0/16 VPC can be subdivided into multiple /24 subnets to match the scale and requirements of different parts of your application.

5. Scalability: By choosing an appropriately sized CIDR block for your VPC, you ensure there is enough address space to scale your infrastructure. For example, a /16 CIDR block provides up to 65,536 IP addresses, which can be subdivided as needed as your application grows.

In the provided Terraform script, the CIDR block is used to define the VPC and subnet configurations:

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.7.0"
name = "demo-eks-vpc"
cidr = var.vpc_cidr
azs = data.aws_availability_zones.available.names
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.4.0/24", "10.0.5.0/24"]
...
}
  • cidr = var.vpc_cidr: The primary CIDR block for the VPC is specified using a variable (var.vpc_cidr), which ensures flexibility.
  • private_subnets: Two private subnets are created with CIDR blocks 10.0.1.0/24 and 10.0.2.0/24.
  • public_subnets: Two public subnets are created with CIDR blocks 10.0.4.0/24 and 10.0.5.0/24.

CIDR is a fundamental concept in IP address allocation and network design, providing flexibility and efficiency. In setting up a VPC in AWS, CIDR notation is essential for defining the IP address range of the VPC and segmenting it into subnets, ensuring organized, scalable, and secure network architecture.

Step-by-Step Guide to Calculate CIDR Range

1. Understand CIDR Notation

CIDR notation consists of an IP address and a suffix indicating the number of bits used for the network part of the address. For example, 192.168.1.0/24.

  • 192.168.1.0: The IP address.
  • /24: The subnet mask, indicating that the first 24 bits are the network part.

2. Convert the Subnet Mask to Binary

The subnet mask /24 means that the first 24 bits of the IP address are used for the network, and the remaining bits are used for host addresses. In binary, this looks like:

  • Subnet Mask: 255.255.255.0
  • Binary: 11111111.11111111.11111111.00000000

3. Calculate the Number of Hosts

To calculate the number of possible hosts in a subnet, you can use the formula 2(32−prefix)−22^{(32 — \text{prefix})} — 22(32−prefix)−2. The subtraction by 2 accounts for the network address and the broadcast address.

  • For /24:
  • Number of host bits: 32−24=832–24 = 832−24=8
  • Number of hosts: 28−2=256−2=2542⁸ — 2 = 256–2 = 25428−2=256−2=254

4. Determine the Range of IP Addresses

The range of IP addresses is determined by setting the host bits to all 0s for the network address and all 1s for the broadcast address.

  • IP Address: 192.168.1.0/24
  • Network Address: 192.168.1.0
  • Binary: 11000000.10101000.00000001.00000000
  • Broadcast Address: 192.168.1.255
  • Binary: 11000000.10101000.00000001.11111111
  • Usable IP Range: 192.168.1.1 to 192.168.1.254

Example Calculations

Example 1: 192.168.1.0/24

  • CIDR Notation: 192.168.1.0/24
  • Network Address: 192.168.1.0
  • Broadcast Address: 192.168.1.255
  • Usable IP Range: 192.168.1.1 to 192.168.1.254

Example 2: 10.0.0.0/16

  • CIDR Notation: 10.0.0.0/16
  • Subnet Mask: 255.255.0.0
  • Binary Subnet Mask: 11111111.11111111.00000000.00000000
  • Network Address: 10.0.0.0
  • Broadcast Address: 10.0.255.255
  • Usable IP Range: 10.0.0.1 to 10.0.255.254
  • Number of Hosts: 2(32−16)−2=216−2=655342^{(32–16)} — 2 = 2^{16} — 2 = 655342(32−16)−2=216−2=65534

Example 3: 172.16.0.0/12

  • CIDR Notation: 172.16.0.0/12
  • Subnet Mask: 255.240.0.0
  • Binary Subnet Mask: 11111111.11110000.00000000.00000000
  • Network Address: 172.16.0.0
  • Broadcast Address: 172.31.255.255
  • Usable IP Range: 172.16.0.1 to 172.31.255.254
  • Number of Hosts: 2(32−12)−2=220−2=10485742^{(32–12)} — 2 = 2^{20} — 2 = 10485742(32−12)−2=220−2=1048574

Tools and Resources

While manual calculations help in understanding, tools like subnet calculators can simplify the process. Some online tools include:

These tools can quickly compute the network address, broadcast address, and usable IP range for any given CIDR notation.

CIDR is a flexible and efficient way to allocate and manage IP address spaces. By understanding how to calculate the CIDR range, you can design and implement network architectures that are scalable and efficient, ensuring optimal utilization of IP addresses in your network.

  • azs: Specifies the availability zones where subnets will be created, retrieved from the data source data.aws_availability_zones.available.names.
  • private_subnets: Lists the CIDR blocks for private subnets.
  • public_subnets: Lists the CIDR blocks for public subnets.
  • enable_nat_gateway: Enables NAT gateways for private subnets to access the internet.
  • single_nat_gateway: When set to true, creates a single NAT gateway to reduce costs.
  • enable_dns_hostnames: Enables DNS hostnames in the VPC.
  • enable_dns_support: Enables DNS resolution in the VPC.

Tags:

  • tags: Adds tags to the VPC resources, using the local variable local.cluster_name for unique identification.
  • public_subnet_tags: Tags for public subnets, including roles for Kubernetes ELB.
  • private_subnet_tags: Tags for private subnets, including roles for internal ELB.

This Terraform module sets up a VPC with public and private subnets across multiple availability zones, with NAT gateway and DNS support enabled. The use of modules, variables, and local variables makes the script modular, reusable, and easy to manage.

Approaches to Creating EKS Clusters Using Terraform

The Terraform AWS EKS module provides several options for creating node groups and profiles. Here’s a brief overview of the different approaches:

  1. EKS Managed Node Groups:
  • Managed by AWS, which handles provisioning, scaling, and updates.
  • Simplifies management and reduces operational overhead.

2. Fargate Profile:

  • Allows running Kubernetes pods on AWS Fargate, a serverless compute engine.
  • Eliminates the need to manage EC2 instances, focusing purely on running containers.

3. Karpenter:

  • An open-source Kubernetes cluster autoscaler built by AWS.
  • Automatically provisions new nodes in response to unscheduled pods.

4. Self-Managed Node Groups:

  • Requires more manual management compared to managed node groups.
  • Offers more control over the configuration and lifecycle of the EC2 instances.

Here’s the code in the main_eks.tf file that sets up an EKS cluster with managed node groups:

module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "20.8.4"
cluster_name = local.cluster_name
cluster_version = var.kubernetes_version
subnet_ids = module.vpc.private_subnets
enable_irsa = true
tags = {
cluster = "demo"
}
vpc_id = module.vpc.vpc_id
eks_managed_node_group_defaults = {
ami_type = "AL2_x86_64"
instance_types = ["t3.medium"]
vpc_security_group_ids = [aws_security_group.all_worker_mgmt.id]
}
eks_managed_node_groups = {
node_group = {
min_size = 2
max_size = 6
desired_size = 2
}
}
}

Explanation of Code

Module Source and Version:

module "eks" {   
source = "terraform-aws-modules/eks/aws"
version = "20.8.4"
  • source: Points to the Terraform AWS EKS module in the Terraform Registry.
  • version: Specifies the version of the module to ensure compatibility and stability.

Cluster Configuration:

cluster_name    = local.cluster_name   
cluster_version = var.kubernetes_version
subnet_ids = module.vpc.private_subnets
  • cluster_name: Name of the EKS cluster, defined as a local variable.
  • cluster_version: Kubernetes version for the cluster, passed as a variable.
  • subnet_ids: List of subnet IDs for the cluster, using the private subnets from the VPC module.

Enable IAM Roles for Service Accounts (IRSA):

enable_irsa = true
  • enable_irsa: Enables IAM Roles for Service Accounts (IRSA) to manage permissions for pods.

Tags:

tags = {     cluster = "demo"   }
  • tags: Tags to be applied to the EKS cluster for identification and organization.

VPC Configuration:

vpc_id = module.vpc.vpc_id
  • vpc_id: VPC ID where the EKS cluster will be deployed, derived from the VPC module.

Managed Node Group Defaults:

eks_managed_node_group_defaults = {     
ami_type = "AL2_x86_64"
instance_types = ["t3.medium"]
vpc_security_group_ids = [aws_security_group.all_worker_mgmt.id] }
  • ami_type: Specifies the Amazon Machine Image (AMI) type for the nodes.
  • instance_types: Defines the EC2 instance types for the node group.
  • vpc_security_group_ids: Security group IDs for the worker nodes.

Managed Node Groups:

eks_managed_node_groups = {     
node_group = {
min_size = 2
max_size = 6
desired_size = 2
}
}
  • node_group: Configuration for the managed node group.
  • min_size: Minimum number of nodes in the node group.
  • max_size: Maximum number of nodes in the node group.
  • desired_size: Desired number of nodes in the node group.

Example of Self-Managed Node Group

To illustrate the setup of a self-managed node group, you would need to manually define the EC2 instances, security groups, and necessary IAM roles and policies.

Self-Managed Node Group Example

Here is a simplified example of defining a self-managed node group:

resource "aws_launch_configuration" "example" {
name = "example-launch-configuration"
image_id = data.aws_ami.eks_worker.id
instance_type = "t3.medium"
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "example" {
desired_capacity = 2
max_size = 6
min_size = 2
launch_configuration = aws_launch_configuration.example.id
vpc_zone_identifier = module.vpc.private_subnets
tag {
key = "kubernetes.io/cluster/${local.cluster_name}"
value = "owned"
propagate_at_launch = true
}
}
  • aws_launch_configuration: Defines the configuration for launching EC2 instances.
  • aws_autoscaling_group: Manages the scaling of EC2 instances in the self-managed node group.

Using the Terraform AWS EKS module simplifies the creation and management of EKS clusters with different types of node groups and profiles. While managed node groups and Fargate profiles reduce operational overhead, self-managed node groups provide greater control. This tutorial provides a comprehensive guide to setting up an EKS cluster using Terraform, with an emphasis on the flexibility offered by the module.

setting up security groups in an Amazon EKS (Elastic Kubernetes Service)

cluster and walk through the code provided in the security-group.tf file.

What is a Security Group?

A security group acts as a virtual firewall for your Amazon instances to control inbound and outbound traffic.

When using EKS, security groups help manage network traffic between the EKS cluster and its nodes, ensuring secure communication and restricting access to authorized sources.

Purpose of Security Groups in EKS

  • Control Access: Restrict access to EKS cluster resources from specified IP ranges or other AWS resources.
  • Define Traffic Rules: Allow or deny traffic based on protocol, port range, and source/destination.
  • Enhance Security: Protect cluster nodes and applications from unauthorized access and potential threats.

Terraform Code for Security Groups

Here’s the code provided in security-group.tf and an explanation of each part:

Security Group for All Worker Management

resource "aws_security_group" "all_worker_mgmt" {
name_prefix = "all_worker_management"
vpc_id = module.vpc.vpc_id
}
  • resource “aws_security_group” “all_worker_mgmt”: Creates a new security group named all_worker_management in the specified VPC.
  • name_prefix: Prefix for the security group name.
  • vpc_id: The ID of the VPC where the security group will be created. This is fetched from the VPC module.

Ingress Rules

resource "aws_security_group_rule" "all_worker_mgmt_ingress" {
description = "allow inbound traffic from eks"
from_port = 0
protocol = "-1"
to_port = 0
security_group_id = aws_security_group.all_worker_mgmt.id
type = "ingress"
cidr_blocks = [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
]
}
  • resource “aws_security_group_rule” “all_worker_mgmt_ingress”: Defines an inbound (ingress) rule for the all_worker_mgmt security group.
  • description: Description of the rule.
  • from_port: Starting port for the allowed traffic. 0 indicates all ports.
  • protocol: Protocol type. -1 means all protocols are allowed.
  • to_port: Ending port for the allowed traffic. 0 indicates all ports.
  • security_group_id: The ID of the security group to which this rule applies.
  • type: The type of rule, which is ingress for inbound traffic.
  • cidr_blocks: List of CIDR blocks from which inbound traffic is allowed. This example allows traffic from private IP ranges.

Egress Rules

resource "aws_security_group_rule" "all_worker_mgmt_egress" {
description = "allow outbound traffic to anywhere"
from_port = 0
protocol = "-1"
security_group_id = aws_security_group.all_worker_mgmt.id
to_port = 0
type = "egress"
cidr_blocks = ["0.0.0.0/0"]
}
  • resource “aws_security_group_rule” “all_worker_mgmt_egress”: Defines an outbound (egress) rule for the all_worker_mgmt security group.
  • description: Description of the rule.
  • from_port: Starting port for the allowed traffic. 0 indicates all ports.
  • protocol: Protocol type. -1 means all protocols are allowed.
  • security_group_id: The ID of the security group to which this rule applies.
  • to_port: Ending port for the allowed traffic. 0 indicates all ports.
  • type: The type of rule, which is egress for outbound traffic.
  • cidr_blocks: List of CIDR blocks to which outbound traffic is allowed. This example allows traffic to any IP address.

Security groups are crucial for managing and securing network traffic to and from your EKS cluster, ensuring that only authorized traffic can access your cluster resources.

By understanding and implementing these security group rules, you can enhance the security of your EKS cluster and maintain better control over your network traffic.

Understanding the Use of Output Variables in Terraform

Output variables in Terraform are a way to extract information from your infrastructure configuration. They allow you to access and use important data from your Terraform-managed infrastructure outside the configuration, such as for integration with other systems, for documentation, or simply for easier access to key pieces of information.

In the context of an EKS (Elastic Kubernetes Service) setup, output variables provide essential details about the created EKS cluster that can be used for further configuration, access, and management.

Here’s the code in the outputs.tf file that sets up output variables

output "cluster_id" {
description = "EKS cluster ID."
value = module.eks.cluster_id
}

output "cluster_endpoint" {
description = "Endpoint for EKS control plane."
value = module.eks.cluster_endpoint
}

output "cluster_security_group_id" {
description = "Security group ids attached to the cluster control plane."
value = module.eks.cluster_security_group_id
}

output "region" {
description = "AWS region"
value = var.aws_region
}

output "oidc_provider_arn" {
value = module.eks.oidc_provider_arn
}

#output "zz_update_kubeconfig_command" {
# value = "aws eks update-kubeconfig --name " + module.eks.cluster_id
# value = format("%s %s %s %s", "aws eks update-kubeconfig --name", module.eks.cluster_id, "--region", var.aws_region)
#}

Explanation of Output Variables in EKS Configuration

Here are the output variables used in the provided EKS configuration code and their importance:

1. cluster_id

output "cluster_id" {
description = "EKS cluster ID."
value = module.eks.cluster_id
}
  • Description: The unique identifier for the EKS cluster.
  • Importance: The cluster ID is needed for various operations, such as updating configurations, scaling the cluster, or for other AWS CLI commands that require the cluster’s ID.

2. cluster_endpoint

output "cluster_endpoint" {
description = "Endpoint for EKS control plane."
value = module.eks.cluster_endpoint
}
  • Description: The URL endpoint for the EKS control plane.
  • Importance: This endpoint is used to communicate with the Kubernetes API server. It’s required for configuring kubectl or any other Kubernetes management tools to interact with your cluster.

3. cluster_security_group_id

output "cluster_security_group_id" {
description = "Security group ids attached to the cluster control plane."
value = module.eks.cluster_security_group_id
}
  • Description: The security group IDs associated with the EKS cluster control plane.
  • Importance: These security group IDs are essential for managing network access to the control plane. They are used to define and control the traffic rules for the cluster.

4. region

output "region" {
description = "AWS region"
value = var.aws_region
}
  • Description: The AWS region where the EKS cluster is deployed.
  • Importance: Knowing the region is crucial for any AWS operations or commands you need to run that are region-specific. This ensures you are interacting with the correct regional resources.

5. oidc_provider_arn

output "oidc_provider_arn" {
value = module.eks.oidc_provider_arn
}
  • Description: The ARN (Amazon Resource Name) of the OIDC (OpenID Connect) provider associated with the EKS cluster.
  • Importance: This is used for IAM roles for service accounts (IRSA), which allow Kubernetes pods to assume AWS IAM roles and access AWS services securely.

6. zz_update_kubeconfig_command (commented out)

# output "zz_update_kubeconfig_command" {
# value = format("%s %s %s %s", "aws eks update-kubeconfig --name", module.eks.cluster_id, "--region", var.aws_region)
# }
  • Description: A command to update the kubeconfig file for kubectl to use the EKS cluster.
  • Importance: This command, when run, configures your local kubectl to interact with the EKS cluster. Although commented out, it's a useful output for quickly setting up the local Kubernetes client configuration.

Step 4: Initialize Terraform

Before applying the configuration, we need to initialize Terraform. Initialization ensures that all required modules and providers are downloaded.

Navigate to the directory containing main.tf and run:

terraform init

Step 5: Apply the Terraform Configuration

With the initialization complete, we can now apply the configuration to create our EKS cluster and VPC. Run the following command:

terraform plan
terraform apply --auto-approve

Terraform will show a plan of the resources it will create. Review the plan and confirm by typing yes.

new cluster is created

To save resources delete cluster after use

terraform destroy

Conclusion

You’ve successfully created an AWS EKS cluster with a VPC using Terraform. You can now start deploying your Kubernetes applications to the cluster. Remember to clean up your resources when they’re no longer needed to avoid incurring unnecessary costs.

Github Repo

🚀

Thank You for reading

Please give 👏🏻 Claps if you like the blog.

Made with ❤️by Vaibhav Hariramani

Don’t forget to tag us

if you find this blog beneficial for you don’t forget to share it with your friends and mention us as well. And Don’t forget to share us on Linkedin, instagram, facebook , twitter, Github

More Resources

To learn more about these Resources you can Refer to some of these articles written by Me:-

Do Checkout My other Blogs

Do find time check out my other articles and further readings in the reference section. Kindly remember to follow me so as to get notified of my publications.

Do Checkout My Youtube channel

Follow me

on Linkedin, instagram, facebook , twitter, Github

Happy coding ❤️ .

--

--

VAIBHAV HARIRAMANI

Hi there! I am Vaibhav Hariramani a Travel & Tech blogger who love to seek out new technologies and experience cool stuff.