Orchestrating Amazon EKS Clusters via HashiCorp Terraform

The deployment of containerized applications has shifted from a luxury to a necessity for modern enterprise software delivery. At the center of this shift is Amazon Elastic Kubernetes Service (EKS), a managed service from Amazon Web Services (AWS) designed to simplify the deployment, management, and scaling of Kubernetes clusters. While AWS provides native tools for provisioning such as the Management Console UI, Command Line Interface (CLI), and CloudFormation, the industry standard for high-velocity engineering teams is Infrastructure as Code (IaC). Terraform, developed by HashiCorp, serves as the premier IaC tool, allowing engineers to define their entire cloud environment in configuration files. By combining AWS EKS with Terraform, organizations can move away from manual "click-ops" and toward a model of reproducible, version-controlled, and automated infrastructure. This synergy eliminates the operational overhead of installing and operating a Kubernetes control plane or managing individual nodes manually, as AWS handles the heavy lifting of the Kubernetes master nodes while Terraform ensures the environment is consistent across development, staging, and production tiers.

Fundamental Architecture and Primary Terminologies

Before executing the deployment of a managed Kubernetes environment, it is critical to understand the conceptual building blocks that make this integration possible.

Terraform
Terraform is an Infrastructure as a Service (IaaS) tool that enables the deployment of resources across multiple cloud providers through a declarative language. By treating infrastructure as code, Terraform allows developers to version their hardware requirements alongside their application code. The impact of using Terraform is the total elimination of configuration drift, where environments diverge over time due to manual tweaks. In the context of EKS, Terraform acts as the orchestrator that tells AWS exactly how the network, security groups, and compute nodes should be configured.

Amazon EKS (Elastic Kubernetes Service)
EKS is a managed Kubernetes service that allows users to run Kubernetes applications on AWS without the burden of installing or operating their own Kubernetes control plane. In a standard Kubernetes setup, the user must manage the API server, the etcd store, and the scheduler. EKS abstracts this entirely, providing a highly available control plane managed by AWS. The real-world consequence is that the engineering team can focus on deploying containers rather than debugging the internal plumbing of Kubernetes itself.

Infrastructure as Code (IaaC)
IaaC is the practice of representing cloud infrastructure in the form of code. This means that instead of manually creating a Virtual Private Cloud (VPC) or a subnet in the AWS Console, a developer writes a text file describing those resources. This practice ensures consistency and repeatability; if a cluster is accidentally deleted, the entire environment can be recreated in minutes by simply running the code again.

The Strategic Advantage of Terraform for EKS Deployments

While AWS offers internal provisioning methods, Terraform provides several architectural advantages that are indispensable for production-ready environments.

Unified Workflow
For organizations already utilizing Terraform for their general AWS infrastructure (such as S3 buckets, RDS databases, or EC BrowserRouter), using it for EKS creates a single, unified workflow. This means that both the underlying infrastructure and the applications residing within the clusters can be managed using the same toolset and pipeline.

Full Lifecycle Management
Terraform maintains a state file that tracks every resource it creates. It can create, update, and delete tracked resources without requiring an operator to manually inspect an API to identify which resources belong to which project. This prevents "zombie resources"—orphaned load balancers or disks that continue to incur costs after a project has ended.

Graph of Relationships
One of the most powerful features of Terraform is its ability to determine and observe dependencies between resources. For instance, an EKS cluster cannot exist without a VPC and specific subnet configurations. Terraform builds a dependency graph; if the VPC provisioning fails, Terraform will intelligently stop the process and not attempt to create the cluster, preventing a cascade of deployment errors.

Comprehensive Environment Preparation

A successful deployment requires a precisely configured local environment. The following prerequisites must be met before writing a single line of HCL (HashiCorp Configuration Language).

Required Software Tooling

  • Terraform (v1.0+): The core engine used to execute the infrastructure plans.
  • AWS CLI: The Command Line Interface used to authenticate the local machine with the AWS cloud.
  • kubectl: The standard Kubernetes command-line tool used for interacting with the cluster once it is online.
  • AWS Account: An active account with IAM permissions sufficient to create VPCs, EC2 instances, and EKS clusters.

Installation Procedures

For users on macOS, Homebrew provides a streamlined installation path. The following commands should be executed in the terminal:

brew install terraform

brew install awscli

brew install kubernetes-cli

For users on Windows or Linux, the manual process involves downloading the Terraform zip file from the official installation page, extracting it to a desired location, and adding the directory path to the system environment variables to ensure the terraform command is runnable from any directory. Similarly, the AWS CLI setup should be downloaded from the official website and run through the standard installer.

AWS CLI Configuration and Authentication

Terraform does not inherently have access to your AWS account; it relies on the credentials configured in the AWS CLI.

The authentication process follows these specific steps:

  1. Access the AWS Management Console and navigate to the IAM section to create or copy an AWS Access Key and Secret Access Key.
  2. Open a terminal or command prompt.
  3. Execute the configuration command:
    aws configure
  4. When prompted, enter the Access Key ID and the Secret Access Key.
  5. Provide the default region (e.g., us-east-1) to ensure Terraform knows where to provision the resources.

This configuration creates a local credentials file that Terraform reads to authorize API calls to AWS. Without this step, any attempt to run terraform plan or terraform apply will result in an authentication error.

Constructing the Terraform Configuration

The core of the deployment resides in the .tf files. The process begins by creating a main.tf file in the project directory.

Defining the Provider and Versioning

The first block in the configuration is the terraform block, which defines the required providers and the minimum version of Terraform needed to execute the code. This prevents the code from running on outdated versions that might not support new AWS features.

hcl terraform { required_providers { aws = { source = "hashicorp/aws" version = "5.37.0" } } required_version = ">= 1.2.0" }

The provider block specifies the cloud region where the EKS cluster will be hosted:

hcl provider "aws" { region = "us-east-1" }

Implementing the EKS Module

To simplify the creation of the cluster, it is recommended to use the official Terraform AWS EKS module. This module abstracts the complexity of creating IAM roles, security groups, and node groups into a few configurable parameters.

```hcl
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.31"

clustername = "sage-nodes"
cluster
version = "1.31"

# Optional: Controls if the Kubernetes API server is accessible from the public internet
clusterendpointpublic_access = true

# Optional: Grants the person running terraform admin rights to the cluster
enableclustercreatoradminpermissions = true

eksmanagednodegroups = {
sage-nodes = {
instance
types = ["t3.medium"]
minsize = 1
max
size = 3
desired_size = 2
}
}

vpcid = awsvpc.main.id
subnetids = awssubnet.public_subnet.*.id

tags = {
Environment = "dev"
Terraform = "true"
}
}
```

This configuration ensures that the cluster is not just a control plane, but includes managed node groups. The t3.medium instance type is specified for the worker nodes, with an auto-scaling configuration that allows the cluster to grow from 1 to 3 nodes, maintaining a desired state of 2.

Infrastructure Components Summary

The execution of the above code results in the creation of a complex web of interconnected AWS resources.

Component Description Purpose
VPC Virtual Private Cloud Provides an isolated network environment for the cluster.
Subnets Public and Private Subnets Distributes nodes across multiple Availability Zones for high availability.
Control Plane AWS-Managed Kubernetes Master Handles orchestration, scheduling, and API requests.
Managed Node Groups EC2 Worker Nodes Provides the actual compute power to run containerized pods.
IAM Roles Identity and Access Management Defines what AWS services the EKS cluster can interact with.
NAT Gateway Network Address Translation Allows private subnet nodes to access the internet for updates.
Internet Gateway Gateway to the public web Enables external traffic to reach the public load balancers.
Route Tables Network Routing Rules Directs traffic between subnets and the internet.

Execution and Deployment Workflow

Once the code is written, a specific sequence of commands must be followed to move from a local text file to a running cloud cluster.

Initializing the Project
The first step is to run the initialization command:
terraform init
This command tells Terraform to look at the required_providers block and download the necessary plugins from the HashiCorp Registry. It also initializes the backend where the state file will be stored.

Generating the Execution Plan
Before applying changes, it is critical to review what Terraform intends to do:
terraform plan
This generates a detailed list of resources that will be created, modified, or destroyed. In a professional DevOps pipeline, this plan is often reviewed by a peer before being applied to production.

Applying the Configuration
To actually provision the resources in AWS, execute:
terraform apply
The user will be prompted to confirm the action by typing yes. Terraform will then communicate with the AWS API and begin creating the VPC, IAM roles, and the EKS cluster. This process typically takes several minutes as Kubernetes bootstraps the control plane and joins the worker nodes to the cluster.

Configuring Cluster Access and Verification

After Terraform completes the deployment, the cluster exists in AWS, but the local kubectl tool is not yet aware of it.

Updating Kubeconfig
To allow kubectl to communicate with the new EKS cluster, you must update the local kubeconfig file using the AWS CLI:
aws eks --region us-east-1 update-kubeconfig --name example

(Note: replace example with the actual cluster_name defined in your Terraform code, such as sage-nodes).

Verifying the Connection
To confirm that the authentication was successful and that you are pointing to the correct cluster, run:
kubectl config current-context

Once the context is verified, you can inspect the health of the worker nodes:
kubectl get nodes
This command lists all the nodes in the cluster. If the managed node groups were provisioned correctly, you should see the t3.medium instances listed as Ready.

Operational Validation via Application Deployment

The final step in verifying a cluster is to deploy a live workload. A common test is deploying an NGINX web server.

Deploying the Pod
Run the following command to create a pod using the NGINX image:
kubectl run --port 80 --image nginx nginx

Checking Pod Status
To ensure the container has been pulled and is running successfully, execute:
kubectl get pods

Establishing Connectivity
To access the NGINX server from your local machine, you can use a port-forwarding tunnel:
kubectl port-forward nginx 3000:80
Now, navigating to http://localhost:3000 in a web browser will serve the NGINX welcome page directly from the EKS cluster.

Resource Decommissioning and Cost Management

Cloud resources incur ongoing costs. When the testing or development phase is complete, it is imperative to remove all provisioned infrastructure to avoid unexpected charges.

Because Terraform tracks every resource created in the state file, you do not need to manually delete each VPC, subnet, or node group in the AWS console. Instead, use the destroy command:
terraform destroy

Terraform will present a plan showing all resources marked for destruction (for example, "Plan: 0 to add, 0 to change, 63 to destroy"). After the user confirms with yes, Terraform will delete the resources in the reverse order of their creation to ensure dependencies are handled correctly. This process is absolute and cannot be undone; all data within the cluster and the cluster configuration itself will be permanently removed.

Critical Analysis of the EKS-Terraform Integration

The integration of AWS EKS and Terraform represents a shift toward "Immutable Infrastructure." By defining the cluster in code, the environment becomes a versioned artifact. If a configuration error causes a cluster to malfunction, the remedy is not to "fix" the cluster in place, but to update the Terraform code and redeploy a fresh, known-good version of the environment.

The use of managed node groups specifically reduces the operational burden on the DevOps engineer. In a self-managed Kubernetes cluster, the engineer is responsible for patching the AMI (Amazon Machine Image), managing the certificates for the nodes, and ensuring the kubelet is running. With EKS managed node groups, AWS handles the patching and updating process, which significantly reduces the security risk associated with unpatched kernel vulnerabilities on worker nodes.

Furthermore, the combination of Terraform's dependency graph and AWS's availability zones ensures that the resulting infrastructure is resilient. By distributing subnets across multiple AZs, the cluster can survive the failure of an entire data center without losing availability, provided the node groups are configured to span those zones. This level of sophistication—which would take hours to configure manually via a UI—is achieved in seconds through a well-structured Terraform module.

Sources

  1. GeeksforGeeks
  2. HashiCorp Developer
  3. Dev.to

Related Posts