Deploy a Kubernetes Application With Terraform and AWS EKS

When it comes to infrastructure provisioning, including the AWS EKS cluster, Terraform is the first tool that comes to mind. Learning Terraform is much easier than setting up the infrastructure manually. That said, would you rather use the traditional approach to set up the infrastructure, or would you prefer to use Terraform? More specifically, would you rather create an EKS cluster using Terraform and have Terraform Kubernetes deployment in place, or use the manual method, leaving room for human errors? 

As you may already know, Terraform is an open-source Infrastructure as Code (IaC) software platform that allows you to manage hundreds of cloud services using a uniform CLI approach and uses declarative configuration files to codify cloud APIs. In this article, we won’t go into all the details of Terraform. Instead, we will be focusing on Terraform Kubernetes deployment.

In summary, we will be looking at the steps to provision an EKS Cluster using Terraform. Also, we will go through how Terraform Kubernetes deployment helps save time and reduce human errors, which can occur when using a traditional or manual approach for application deployment.

Prerequisites for Terraform Kubernetes Deployment

Before we proceed and provision EKS cluster using Terraform, there are a few commands (or tools) you need to have in mind and on hand. First off, you must have an AWS Account, and Terraform must be installed on your host machine, seeing as we are going to create an EKS cluster using Terraform CLI on the AWS cloud. 

Now, let’s take a look at the prerequisites for this setup and help you install them:

AWS Account

If you don’t have an AWS account, you can register for a “Free Tier Account” and use it for test purposes.

IAM Admin User

You must have an IAM user with AmazonEKSClusterPolicy and AdministratorAccess permissions as well as its secret and access keys. We will be using the IAM user credentials to provision an EKS cluster using Terraform. The keys you create for this user will be used to connect to the AWS account from the CLI (Command Line Interface). When working on production clusters, only provide the required access and avoid providing admin privileges.


EC2 Instance

We will be using the Ubuntu 18.04 EC2 Instance as a host machine to execute our Terraform code. You may use another machine, however, you will need to verify which commands are compatible with your host machine to install the required packages. The first step is installing the required packages on your machine. You can also use your personal computer to install the required tools. This step is optional.

Optional Step

Access to the Host Machine

  1. Connect to the EC2 Instance and install the “unzip package:ssh -i “<key-name.pem>” ubuntu@<public-ip-of-the–ec2-instance>.
  2. If you are using your personal computer, you may not need to connect to the EC2 instance. However, in this case, the installation command will differ.
  3. sudo apt-get update -y.
  4. sudo apt-get install unzip -y.

Terraform

To create an EKS cluster using Terraform, you need to have Terraform on your host machine. Use the following commands to install Terraform on an Ubuntu 18.04 EC2 machine. Visit Hashicorps official website to view the installation instructions for other platforms.

  1. sudo apt-get update and sudo apt-get install -y gnupg software-properties-common curl.
  2. cur—fsSL | sudo “apt-key” add (here).
  3. sudo apt-add-repository deb [arch=amd64] $(lsb_release -cs) main (here).
  4. sudo “apt-get” update and sudo “apt-get” install Terraform.
  5. Terraform—version:

Terraform Version

AWS CLI

There is not much to do with aws-cli, however, we need to use it to check the details about the IAM user whose credentials will be used from the terminal. To install it, use the commands below:
  1. curl (here) -o “awscliv2.zip”
  2. unzip awscliv2.zip
  3. sudo ./aws/install
Kubectl

Kubectl

We will be using the kubectl command against the Kubernetes cluster to view the resources in the EKS cluster we want to create. Install kubectl on Ubuntu 18.04 EC2 machine using the commands below:

  1. curl -LO “curl -L -s (here) /bin/linux/amd64/kubectl
  2. url -LO “curl -L -s (here) /bin/linux/amd64/kubectl.sha256
  3. echo “$(cat kubectl.sha256) kubectl” | sha256sum –check
  4. sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
  5. kubectl versio—client
Kubectl 2

DOT

Note: This is completely optional. We will be using this to convert the output of the Terraform graph command. The output of the Terraform graph command is in DOT format, which can easily be converted into an image by making use of the DOT provided by GraphViz. The Terraform graph command is used to generate a visual representation of a configuration or execution plan.

To install the DOT command, execute this command: sudo apt install graphvi

Export Your AWS Access and Secret Keys for the Current Session

If the session expires, you will need to export the keys again on the terminal. There are other ways to use your keys that allow aws-cli to interact with AWS:

  1. Export AWS_ACCESS_KEY_ID=<YOUR_AWS_ACCESS_KEY_ID>.
  2. Export AWS_SECRET_ACCESS_KEY=<YOUR_AWS_SECRET_ACCESS_KEY>.
  3. Export AWS_DEFAULT_REGION=<YOUR_AWS_DEFAULT_REGION>Here, replace <YOUR_AWS_ACCESS_KEY_ID> with your access key, <YOUR_AWS_SECRET_ACCESS_KEY> with your secret key, and <YOUR_AWS_DEFAULT_REGION> with the default region for your aws-cli.

Check the Details of the IAM User Whose Credentials Are Being Used

Basically, this will display the details of the user whose keys you used to configure the CLI in the above step:

  1. aws sts get-caller-identity:

IAM User

Architecture 

The architecture should appear as follows.

A VPC will be created with three public subnets and three private subnets. Traffic from private subnets will route through the NAT gateway and traffic from public subnets will route through the internet gateway. 

Kubernetes cluster nodes will be created as part of auto-scaling groups and will reside in private subnets. Public subnets can be used to create bastion servers that can be used to connect to private nodes.

Three public subnets and three private subnets will be created in three different availability zones.

You can change the VPC CIDR in the Terraform configuration files if you wish. If you are just getting started, we recommend following the article without making any unfamiliar changes to the configuration in to avoid human errors.

Kubernetes Cluster Nodes

Highlights

This article will help you provision an EKS cluster using Terraform and deploy a sample NodeJs application. When creating an EKS cluster, other AWS resources such as VPC, subnets, NAT gateway, internet gateway, and security groups will also be created on your AWS account. This article is divided into two parts:  

  1. The creation of an EKS cluster using Terraform.
  2. Deployment of a sample Nodejs application in the EKS cluster using Terraform.

First off, we will create an EKS cluster. After which, we will deploy a sample Nodejs application on it using Terraform. In this article, we refer to Terraform Modules for creating VPC, and its components, along with the EKS cluster. 

Here is a list of some of the Terraform elements we’ll use:

  1. Module: A module is made up of a group of of .tf and/or .tf.jsonfiles contained in a directory. Modules are containers for a variety of resources that are used in conjunction. Terraform’s main method of packaging and reusing resource configurations is through modules.
    1. EKS: We will be using a terraform-aws-modules/eks/aws module to create our EKS cluster and its components.
    2. VPC: We will be using a terraform-aws-modules/vpc/aws module to create our VPC and its components.
  2. Data: The Data source is accessed by a data resource, which is specified using a data block and allows Terraform to use the information defined outside of Terraform, defined within another Terraform configuration, or changed by functions.
  3. Provider: Provider is a Terraform plugin that allows users to communicate with cloud providers, SaaS providers, and other APIs. Terraform configurations must specify the required providers in order for Terraform to install and use them.
    1. Kubernetes: The Kubernetes provider is used to communicate with Kubernetes’ resources. Before the provider can be utilized, it must be configured with appropriate credentials. For this example, we will use host, token, and cluster_ca_certificate in the provider block.
    2. AWS: The AWS provider is used to communicate with AWS’ resources. Before the provider can be utilized, it must be configured with the appropriate credentials. In this case, we will export AWS access and secret keys to the terminal.
  4. Resource: The most crucial element of the Terraform language is resources. Each resource block describes one or more infrastructure items. A resource block specifies a particular kind of resource with a specific local name. The resource type and name serve to identify a resource and, therefore, must be distinct inside a module.
    1. kubernetes_namespace: We will be using a kubernetes_namespace to create namespaces in our EKS cluster.
    2. kubernetes_deployment: We will be using a kubernetes_deployment to create deployments in our EKS cluster.
    3. kubernetes_service: We will be using a kubernetes_service to create services in our EKS cluster.
    4. aws_security_group: We will be using aws_security_group to create multiple security groups for instances that will be created as part of our EKS cluster.
    5. random_string: Random string is a resource that generates a random permutation of alphanumeric and special characters. We will be creating a random string that will be used as a suffix in our EKS cluster name.
  5. Output: Output values provide information about your infrastructure to other Terraform setups and make said information available on the command line. In computer languages, output values are equivalent to return values. An output block must be used to declare each output value that a module exports.
  6. Required_versionThe required_version parameter accepts a version constraint string that determines which Terraform versions are compatible with your setup. Only the Terraform CLI version is affected by the required version parameter.
  7. Variable: Terraform variables, including variables in any other programming language, allow you to tweak the characteristics of Terraform modules without modifying the module’s source code. This makes your modules composable and reusable by allowing you to exchange modules across multiple Terraform settings. Variables can include past values, which can be utilized when calling the module or running Terraform.
  8. Locals: A local value gives an expression a name, allowing you to use it numerous times within a module without having to repeat it.

Before we go ahead and create EKS cluster using Terraform, let’s take a look at why Terraform is a good choice.

Why Provision and Deploy With Terraform?

It’s normal to wonder “why provision EKS cluster using Terraform?” or “why create EKS cluster using Terraform?” when we can simply achieve the same with the AWS Console, AWS CLI, or other tools. Here are a few of the reasons why: 

  1. Unified workflow: If you’re already using Terraform to deploy infrastructure to AWS, your EKS cluster can be integrated into that process. Also, Terraform can be used to deploy applications into your EKS cluster.
  2. Full lifecycle management: Terraform not only creates resources, but also updates and deletes tracked resources without you having to inspect the API to find those resources.
  3. Graph of relationships: Terraform recognizes resource-dependent relationships via a relationship graph. If, for example, an AWS Kubernetes cluster requires specified VPC and subnet configurations, Terraform will not attempt to create the cluster if the VPC and subnets fail to create it with the required configuration.

How To Create an EKS Cluster Using Terraform

In this part of the article, we shall provision an EKS cluster using Terraform. While doing this, other dependent resources like VPC, Subnets, NAT Gateway, Internet Gateway, and Security Groups will also be created, and we will also deploy an Nginx application with Terraform.

Note: You can find all of the relevant code on my Github repository. Before you create an EKS cluster with Terraform using the following steps, you need to set up and make note of a few things:

  1. Clone the Github repository in your home directory:
    1. cd ~/
    2. pwd
    3. git clone

GitHub Repository

  1. After you clone the repo, change your “Present Working Directory” to ~/DevOps/aws/terraform/terraform-kubernetes-deployment/
    1. cd ~/DevOps/aws/terraform/terraform-kubernetes-deployment/
provision EKS Cluster using Terraform step 2
  1. The Terraform files for creating an EKS cluster must be in one folder and the Terraform files for deploying a sample NodeJs application must be in another.
    1. eks-cluster: This folder contains all of the .tf files required for creating the EKS Cluster.
    2. nodejs-application: This folder contains a .tf file required for deploying the sample NodeJs application.

Now, let’s proceed with the creation of an EKS cluster using Terraform:

  1. Verify your “Present Working Directory,” it should be ~/DevOps/aws/terraform/terraform-kubernetes-deployment/as you have already cloned my Github repository in the previous step.
    1. cd ~/DevOps/aws/terraform/terraform-kubernetes-deployment/
  2. Next, change your “Present Working Directory” to ~/DevOps/aws/terraform/terraform-kubernetes-deployment/eks-cluster
    1. cd ~/DevOps/aws/terraform/terraform-kubernetes-deployment/eks-cluster
  3. You should now have all the required files:

Required Files

  1. If you haven’t cloned the repo then you are free to create the required .tf files in a new folder.
  2. Create your eks-cluster.tf file with the content below. In this case, we are using the module from terraform-aws-modules/eks/aws to create our EKS Cluster. Let’s take a look at the most important inputs that you may want to consider changing depending on your requirements.
    1. Source: This informs Terraform of the location of the source code for the module.
    2. Version: It is recommended to explicitly specify the acceptable version number to avoid unexpected or unwanted changes.
    3. cluster_name: The cluster name is passed from the local variable.
    4. cluster_version: This defines the EKS cluster version.
    5. Subnets: This specifies the list of Subnets in which nodes will be created. For this example, we will be creating nodes in the “Private Subnets.” Subnet IDs are passed here from the module in which Subnets are created.
    6. cpc_id: This specifies the VPI in which the EKS cluster will be created. The value is passed from the module in which the VPC is created.
    7. instance_type: You can change this value if you want to create worker nodes with any other instance type.
    8. asg_desired_capacity: Here, you can specify the maximum number of nodes that you want in your auto-scaling worker node groups.
module “eks” {
  source          = “terraform-aws-modules/eks/aws”
  version         = “17.24.0”
  cluster_name    = local.cluster_name
  cluster_version = “1.20”
  subnets         = module.vpc.private_subnets

  vpc_id = module.vpc.vpc_id

  workers_group_defaults = {
    root_volume_type = “gp2”
  }

  worker_groups = [
    {
      name                          = “worker-group-1”
      instance_type                 = “t2.small”
      additional_userdata           = “echo nothing”
      additional_security_group_ids = [aws_security_group.worker_group_mgmt_one.id]
      asg_desired_capacity          = 2
    },
    {
      name                          = “worker-group-2”
      instance_type                 = “t2.medium”
      additional_userdata           = “echo nothing”
      additional_security_group_ids = [aws_security_group.worker_group_mgmt_two.id]
      asg_desired_capacity          = 1
    },
  ]
}

data “aws_eks_cluster” “cluster” {
  name = module.eks.cluster_id
}

data “aws_eks_cluster_auth” “cluster” {
  name = module.eks.cluster_id
}

  1. Create a kubernetes.tf file with the following content. Here, we are using Terraform Kubernetes Provider to create Kubernetes objects, such as a namespace, deployment, and service, using Terraform. We are creating these resources for testing purposes only. In the following steps, we will also be deploying a sample application using Terraform. Here are all the resources we will be creating in the EKS cluster.
    1. kubernetes_namespace: We will be creating a “test” namespace and using this namespace to create other Kubernetes objects in the EKS cluster.
    2. kubernetes_deployment: We will be creating a deployment with two replicas of the Nginx pod.
    3. kubernetes_service: A service of type LoadBalancer will be created and used to access our Nginx application.
provider “kubernetes” {
  host                   = data.aws_eks_cluster.cluster.endpoint
  token                  = data.aws_eks_cluster_auth.cluster.token
  cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
}


resource “kubernetes_namespace” “test” {
  metadata {
    name = “nginx”
  }
}
resource “kubernetes_deployment” “test” {
  metadata {
    name      = “nginx”
    namespace = kubernetes_namespace.test.metadata.0.name
  }
  spec {
    replicas = 2
    selector {
      match_labels = {
        app = “MyTestApp”
      }
    }
    template {
      metadata {
        labels = {
          app = “MyTestApp”
        }
      }
      spec {
        container {
          image = “nginx”
          name  = “nginx-container”
          port {
            container_port = 80
          }
        }
      }
    }
  }
}
resource “kubernetes_service” “test” {
  metadata {
    name      = “nginx”
    namespace = kubernetes_namespace.test.metadata.0.name
  }
  spec {
    selector = {
      app = kubernetes_deployment.test.spec.0.template.0.metadata.0.labels.app
    }
    type = “LoadBalancer”
    port {
      port        = 80
      target_port = 80
    }
  }
}

  1. Create an outputs.tf file with the following content. This is done to export the structured data related to our resources. It will provide information about our EKS infrastructure to other Terraform setups. Output values are equivalent to return values in other programming languages.
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 “kubectl_config” {
  description = “kubectl config as generated by the module.”
  value       = module.eks.kubeconfig
}

output “config_map_aws_auth” {
  description = “A kubernetes configuration to authenticate to this EKS cluster.”
  value       = module.eks.config_map_aws_auth
}

output “region” {
  description = “AWS region”
  value       = var.region
}

output “cluster_name” {
  description = “Kubernetes Cluster Name”
  value       = local.cluster_name
}

  1. Create a security-groups.tf file with the following content. In this case, we are defining the security groups, which will be used by our worker nodes.
resource “aws_security_group” “worker_group_mgmt_one” {
  name_prefix = “worker_group_mgmt_one”
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port = 22
    to_port   = 22
    protocol  = “tcp”

    cidr_blocks = [
      “10.0.0.0/8”,
    ]
  }
}

resource “aws_security_group” “worker_group_mgmt_two” {
  name_prefix = “worker_group_mgmt_two”
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port = 22
    to_port   = 22
    protocol  = “tcp”

    cidr_blocks = [
      “192.168.0.0/16”,
    ]
  }
}

resource “aws_security_group” “all_worker_mgmt” {
  name_prefix = “all_worker_management”
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port = 22
    to_port   = 22
    protocol  = “tcp”

    cidr_blocks = [
      “10.0.0.0/8”,
      “172.16.0.0/12”,
      “192.168.0.0/16”,
    ]
  }
}

  1. Create a versions.tf file with the following content. Here, we are defining version constraints along with a provider as AWS.
terraform {
  required_providers {
    aws = {
      source  = “hashicorp/aws”
      version = “>= 3.20.0”
    }

    random = {
      source  = “hashicorp/random”
      version = “3.1.0”
    }

    local = {
      source  = “hashicorp/local”
      version = “2.1.0”
    }

    null = {
      source  = “hashicorp/null”
      version = “3.1.0”
    }

    kubernetes = {
      source  = “hashicorp/kubernetes”
      version = “>= 2.0.1”
    }
  }

  required_version = “>= 0.14”
}

  1. Create a vpc.tf file with the following content. For the purposes of our example, we have defined a 10.0.0.0/16 CIDR for a new VPC that will be created and used by the EKS cluster. We will also be creating public and private Subnets. To create a VPC, we will be using the terraform-aws-modules/vpc/aws module. All of our resources will be created in the us-east-1 region. If you want to use any other region for creating the EKS cluster, all you need to do is change the value assigned to the “region” variable.
variable “region” {
  default     = “us-east-1”
  description = “AWS region”
}

provider “aws” {
  region = var.region
}

data “aws_availability_zones” “available” {}

locals {
  cluster_name = “test-eks-cluster-${random_string.suffix.result}”
}

resource “random_string” “suffix” {
  length  = 8
  special = false
}

module “vpc” {
  source  = “terraform-aws-modules/vpc/aws”
  version = “3.2.0”

  name                 = “test-vpc”
  cidr                 = “10.0.0.0/16”
  azs                  = data.aws_availability_zones.available.names
  private_subnets      = [“10.0.1.0/24”, “10.0.2.0/24”, “10.0.3.0/24”]
  public_subnets       = [“10.0.4.0/24”, “10.0.5.0/24”, “10.0.6.0/24”]
  enable_nat_gateway   = true
  single_nat_gateway   = true
  enable_dns_hostnames = 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”
  }
}

  1. At this point, you should have six files in your current directory (as can be seen below). All of these files should be in one directory. In the next step, you will learn to deploy a sample NodeJs application and, to do so, you will need to create a new folder. That said, if you have cloned the repo herein, you won’t need to worry:
    1. eks-cluster.tf
    2. kubernetes.tf
    3. outputs.tf
    4. security-groups.tf
    5. versions.tf
    6. vpc.tf
create EKS Cluster using Terraform step 11
  1. To create an EKS cluster, execute the following command to initialize the current working directory containing the Terraform configuration files (.tffiles).
    1. terraform init

Terraform Init

  1. Execute the following command to determine the desired state of all the resources defined in the above .tffiles.
    1. terraform plan
Terraform Plan
  1. Before we go ahead and create our EKS cluster, let’s take a look at the “terraform graph” command. This is an optional step that you can skip if you wish. Basically, we are simply generating a visual representation of our execution plan. Once you execute the following command, you will get the output in a graph.svgfile. You can try to open the file on your personal computer or online with SVG Viewer.
    1. terraform graph -type plan | dot -Tsvg > graph.svg
  2. We must now create the resources using the .tffiles in our current working directory. Execute the following command. This will take around ten minutes to complete. Feel free to go have a cup of coffee. Once the command is successfully completed, the EKS cluster will be ready.
    1. terraform apply

Terraform Apply

16. After the “terraform apply” command is successfully completed, you should see the output as depicted below.

create EKS Cluster using Terraform step 16
create EKS Cluster using Terraform step 16

17. You can now go to the AWS Console and verify the resources created as part of the EKS cluster.

  1. EKS cluster
create EKS Cluster using Terraform step 17

      2. VPC

create EKS Cluster using Terraform step 17

      3. EC2 Instance

create EKS Cluster using Terraform step 17

      4. EC2 AutoScaling Groups

create EKS Cluster using Terraform step 17

You can check for other resources in the same way.

18. Now, if you try to use the kubectl command to connect to the EKS cluster and control it, you will get an error seeing as you have the kubeconfig file being used for authentication purposes.

  1. kubectl get nodes

Kubectl get nodes

  1. To resolve the error mentioned above, retrieve the access credentials, i.e. update the ~/.kube/config file for the cluster and automatically configure kubectl so that you can connect to the EKS cluster using the kubectlcommand. Execute the following command from the directory where all your .tffiles used to create the EKS cluster are located.
    1. aws eks —region $(terraform output -raw region) update-kubeconfi—name $(terraform output -raw cluster_name)

Kube Config

  1. Now, you are ready to connect to your EKS cluster and check the nodes in the Kubernetes cluster using the following command:
    1. kubectl get nodes
Kubectl Get Nodes
  1. Check the resources such as pods, deployments, and services that are available in the Kubernetes cluster across all namespaces.
    1. kubectl get pod—A
    2. kubectl get deployment—A
    3. kubectl get service—A
    4. kubectl  get ns

Screenshot 21

In the screenshot above, you can see the namespace, pods, deployment, and service we created with Terraform.

We have now attempted to create an EKS cluster using Terraform and deploy Nginx with Terraform. Now, let’s see if we can deploy a sample NodeJs application using Terraform in the same EKS cluster. This time, we will keep the Kubernetes objects files in a separate folder so the NodeJs application can be managed independently, allowing us to deploy and/or destroy our NodeJs application without affecting the EKS cluster.

Deploying a Sample Nodejs Application on the EKS Cluster Using Terraform?

In this part of the article, we will deploy a sample NodeJs application and its dependent resources, including namespace, deployment, and service. We have used the publicly available Docker Images for the sample NodeJs application and MongoDB database.

Now, let’s go ahead with the deployment.

  1. Change your “Present Working Directory” to ~/DevOps/aws/terraform/terraform-kubernetes-deployment/nodejs-application/if you have cloned my repository.
    1. cd ~/DevOps/aws/terraform/terraform-kubernetes-deployment/nodejs-application/
  2. You should now have the required file. 

Required File

  1. If you haven’t cloned the repo, feel free to create the required .tf file in a new folder. Please note that we are using a separate folder here.
  2. Create a sample-nodejs-application.tf file with the following content. In this case, we are using a Terraform Kubernetes Provider to deploy a sample NodeJs application. We will be creating a namespace, NodeJs deployment, and its service of type LoadBalancer, and MongoDB Deployment, as well as its service for type.
provider “kubernetes” {
  config_path    = “~/.kube/config”

}


resource “kubernetes_namespace” “sample-nodejs” {
  metadata {
    name = “sample-nodejs”
  }
}

resource “kubernetes_deployment” “sample-nodejs” {
  metadata {
    name      = “sample-nodejs”
    namespace = kubernetes_namespace.sample-nodejs.metadata.0.name
  }
  spec {
    replicas = 1
    selector {
      match_labels = {
        app = “sample-nodejs”
      }
    }
    template {
      metadata {
        labels = {
          app = “sample-nodejs”
        }
      }
      spec {
        container {
          image = “learnk8s/knote-js:1.0.0”
          name  = “sample-nodejs-container”
          port {
            container_port = 80
          }
          env {
              name = “MONGO_URL”
              value = “mongodb://mongo:27017/dev”

        }

      }
    }
  }
}
}

resource “kubernetes_service” “sample-nodejs” {
  metadata {
    name      = “sample-nodejs”
    namespace = kubernetes_namespace.sample-nodejs.metadata.0.name
  }
  spec {
    selector = {
      app = kubernetes_deployment.sample-nodejs.spec.0.template.0.metadata.0.labels.app
    }
    type = “LoadBalancer”
    port {
      port        = 80
      target_port = 3000
    }
  }
}

resource “kubernetes_deployment” “mongo” {
  metadata {
    name      = “mongo”
    namespace = kubernetes_namespace.sample-nodejs.metadata.0.name
  }
  spec {
    replicas = 1
    selector {
      match_labels = {
        app = “mongo”
      }
    }
    template {
      metadata {
        labels = {
          app = “mongo”
        }
      }
      spec {
        container {
          image = “mongo:3.6.17-xenial”
          name  = “mongo-container”
          port {
            container_port = 27017
          }
      }
    }
  }
}
}


resource “kubernetes_service” “mongo” {
  metadata {
    name      = “mongo”
    namespace = kubernetes_namespace.sample-nodejs.metadata.0.name
  }
  spec {
    selector = {
      app = kubernetes_deployment.mongo.spec.0.template.0.metadata.0.labels.app
    }
    type = “ClusterIP”
    port {
      port        = 27017
      target_port = 27017
    }
  }
}

  1. At this point, you should have one file in your current directory, as depicted below:
    1. sample-nodejs-application.tf
Sample NodeJs Application
  1.  To initialize the current working directory containing our Terraform configuration file (.tffile) and deploy a sample NodeJs application, execute the following command:
    1. terraform  init

Terraform Init 2

  1. Next, execute the following command to determine the desired state of all the resources defined in the above .tffile:
    1. terraform plan
Deploy a Sample Nodejs Application on the EKS Cluster Using Terraform step 7
  1. Before we deploy a sample NodeJs application, let’s try generating a visual representation of our execution plan in the same way we did while creating the EKS cluster. In this case, this is an optional step that you can skip if you don’t wish to see the graph. Once you execute the following command, you will get the output in a graph.svgfile. You can try to open the file on your personal computer or online with SVG Viewer.
    1. terraform grap—type plan | dot -Tsvg > graph.svg
  2. The next step is to deploy the sample Nodejs application using the .tffiles in our current working directory. Execute the following command, and this time, don’t go and have a cup of tea seeing as it should not take more than one minute to complete. Once the command is successfully completed, the sample NodeJs application will be deployed in the EKS cluster using Terraform:
    1. terraform apply

Terraform Apply 2

10. Once the “terraform apply” command is successfully completed, you should see the following output:Deploy a Sample Nodejs Application on the EKS Cluster Using Terraform step 10

11. You can now verify the objects that have been created using the commands below

  1. kubectl get pods -A
  2. kubectl get deployments -A
  3. kubectl get services -A

Step 11

In the above screenshot, you can see the namespace, pods, deployment, and service that were created for the sample NodeJs application.

  1. You can also access the sample NodeJs application using the DNS of the LoadBalancer. Upload an image and add a note to it. Once you’ve published the image, it will be saved in the database.
    It’s important to note that, in this case, we did not use any type of persistent storage for the application, therefore the data will not be retained after the pod is recreated or deleted. To retain data, try using PersistentVolume for the database.
Deploy a Sample Nodejs Application on the EKS Cluster Using Terraform step 12
Deploy a Sample Nodejs Application on the EKS Cluster Using Terraform step 12

We just deployed a sample NodeJs application that was publicly accessible over the LoadBalancer DNS using Terraform.

Next, we will complete the creation of the EKS Cluster and deployment of the sample NodeJs application using Terraform.

Cleanup the Resources We Created

It’s always better to delete the resource once you’re done with the tests, seeing as this saves costs. To clean up the resources and delete the sample NodeJs application and EKS cluster, follow the steps below:

  1. Destroy the sample NodeJs application using the following command:
    1. terraform init
      Execute this command if you get this error: “Error: Inconsistent dependency lock file.”
    2. terraform destroy

Terraform Destroy 3

  1. You should see the following output once the above command is successful:
Cleanup the Resources Created step 2
  1. Validate whether or not the NodeJs application has been destroyed:
    1. kubectl get pod—A
    2. kubectl get deployment—A
    3. kubectl get service—A

Above Screenshot

In the above screenshot you can see that all of the sample Nodejs application resources have been deleted.

  1. Now, let’s destroy the EKS cluster using the following command:
    1. terraform init: Execute this command if you get the following error: “Error: Inconsistent dependency lock file.”
    2. terraform destroy
Cleanup the Resources Created step 4

5. You will see the following output once the above command is successful.

Cleanup the Resources Created step 5

6. You can now go to the AWS console to verify whether or not the resources have been deleted. 

There you have it! We have just successfully deleted the EKS cluster, as well as the sample NodeJs application.

Conclusion of Terraform Kubernetes Deployment

Elastic Kubernetes Service (EKS) is a managed Kubernetes service provided by AWS, which takes the complexity and overhead out of provisioning and optimizing a Kubernetes cluster for development teams. An EKS cluster can be created using a variety of methods; nevertheless, using the best possible way is critical in improving the infrastructure management lifecycle.

Terraform is one of the Infrastructure as Code (IaC) tools that allows you to create, modify, and version control cloud and on-premise resources in a secure and efficient manner. You can use the Terraform Kubernetes deployment method to create an EKS cluster using Terraform while automating the creation process of the EKS Cluster and having additional control over the entire infrastructure management process through code. The creation of the EKS cluster and the deployment of Kubernetes objects can also be managed using the Terraform Kubernetes provider.


Source link