August 20, 2021
Provision an Amazon EKS cluster with Terraform
Kubernetes has gained a lot of traction in the recent years and is now widely used to deliver modern applications. However it becomes extremely cumbersome to provision and maintain Kubernetes clusters (whether on-prem or on cloud). Amazon EKS (Elastic Kubernetes Service) is a managed Kubernetes service that helps users to provision highly available and secure clusters where users can focus on deploying their apps rather than operationalization.
In this blog article we will discuss how to provision a EKS cluster using a popular open source IaC (Infrastructure as Code) tool, Terraform.
Prerequisites
- Terraform should have been installed.
- An AWS account with IAM user provisioned with sufficient privileges required to perform the necessary actions.
- An Amazon VPC (Virtual Private Cloud) must exist with appropriate configurations required to set up EKS.
Create a terraform configuration file
Let’s start by creating new file main.tf
in the designated directory and copy the following contents in the file
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.20"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = “~> 2.0.0"
}
}
required_version = ">= 0.14"
}
provider "aws" {
region = "us-east-1"
}
data "aws_eks_cluster" "cluster" {
name = module.eks.cluster_id
}
data "aws_eks_cluster_auth" "cluster" {
name = module.eks.cluster_id
}
provider "kubernetes" {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
token = data.aws_eks_cluster_auth.cluster.token
load_config_file = false
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = "eks-cluster"
cluster_version = "1.12"
vpc_id = "vpc-3EXAMPLE" # replace with actual vpc-id
subnets = [ "subnet-1EXAMPLE", "subnet-2EXAMPLE", "subnet-3EXAMPLE" ] # replace with actual subnet-ids
node_groups = {
eks_nodes = {
desired_capacity = 3
max_capacity = 3
min_capaicty = 3
instance_type = "t2.small"
}
}
tags = {
Environment = "Prod"
}
}
Run the terraform configuration file
As discussed in our previous blog on Terraform basics, Let us now run the necessary commands to initialize and apply the configuration.
$ terraform init
Initializing modules...
Downloading terraform-aws-modules/eks/aws 17.1.0 for eks...
- eks in .terraform/modules/eks
- eks.fargate in .terraform/modules/eks/modules/fargate
- eks.node_groups in .terraform/modules/eks/modules/node_groups
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 3.20"…
- Installing hashicorp/aws v3.20.0…
- Installed hashicorp/aws v3.20.0 (signed by HashiCorp)
- Finding hashicorp/kubernetes versions matching "~> 2.0.0"…
- Installing hashicorp/aws v2.0.0…
- Installed hashicorp/aws v2.0.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
To validate the Terraform syntax we would have to run :
$ terraform validate
Success! The configuration is valid.
Now, to see a detailed outline of the changes we would have to run terraform plan
. This should include the EKS cluster, and other AWS resources that will be created.
$ terraform plan
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
## ...
Plan: 59 to add, 0 to change, 0 to destroy.
Please note that this snippet has been been edited to limit the size of this article.
------------------------------------------------------------------------
Make sure to review the changes. Assuming everything looks good, you should be able to run terraform apply
against the configuration.
$ terraform apply
Apply complete! Resources: 59 added, 0 changed, 0 destroyed.
Please note that this snippet has been been edited to limit the size of this article.
The terraform apply
will usually take around 15-20 minutes to complete and will create an EKS cluster with all the necessary components.
Download kubeconfig
to start interacting with the cluster
To interact with the provisioned EKS cluster, we would have to run aws eks --region us-east-1 update-kubeconfig --name eks-cluster
in order to use kubectl
.
That’s it, we should now be able to run kubectl
commands on the EKS cluster
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.1", GitCommit:"4ed3216f3ec431b140b1d899130a69fc671678f4", GitTreeState:"clean", BuildDate:"2018-10-05T16:46:06Z", GoVersion:"go1.10.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"12+", GitVersion:"v1.12.6-eks-d69f1b", GitCommit:"d69f1bf3669bf00b7f4a758e978e0e7a1e3a68f7", GitTreeState:"clean", BuildDate:"2019-02-28T20:26:10Z", GoVersion:"go1.10.8", Compiler:"gc", Platform:"linux/amd64"}
TL;DR
Modern day apps are containerized and require container orchestration engines such as kubernetes. Amazon EKS takes away a lot of overhead that is incurred to run and maintain kubernetes clusters in the cloud. However there are still many configurations and add-ons in the cloud, that are needed to run containerized workloads efficiently. This may vary based on the nature and type of workloads.
Need help with setting up Terraform and EKS? Get in touch !