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.


image of Terraform and Amazon EKS


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 !