Hands-On with Terraform Part II - Creating a k8s cluster in DigitalOcean

Hands-On with Terraform Part II - Creating a k8s cluster in DigitalOcean

Feb 8, 2023

In the first part of this article series, we discussed the process of creating a DigitalOcean VPC and a Droplet using Terraform. To fully grasp the concepts discussed in this article, I highly recommend you check out Part I of this series. You can find it here: https://aabishkar.info.np/blogs/hands-on-with-terraform-part-i-creating-a-digitalocean-vpc-and-droplet

In this article, we will create Kubernetes (k8s) cluster with an auto-scaling in DigitalOcean using Terraform. We'll be building a Virtual Private Cloud (VPC) and within it, setting up the k8s cluster. Additionally, we'll cover the various resources required in Terraform file to complete this setup in the DigitalOcean cloud.

So, let's begin.

I am assuming, now you must already have read Part I of this article series and you already have Terraform installed on your machine. The next step is to create a directory inside your projects folder, that you can name anything such as infrastructure, provision or terraform , terraformk8s.

After creating the directory, create a main.tf file inside it where we will put all our DigitalOcean server configurations. Inside the main.tf file, insert the following code. But don't worry, I will explain everything used in this file in a simple manner.

terraform {
  required_providers {
    digitalocean = { # Name of the provider
      source = "digitalocean/digitalocean" # Source of the provider
      version = "~> 2.0" # Version of the provider
    }
  }
}

# Set the variable value in *.tfvars file
# or using -var="do_token=..." CLI option
variable "do_token" {}

# Configure the DigitalOcean Provider
provider "digitalocean" {
  token = var.do_token
}

# Create a VPC with name "terraform-k8s-network"
resource "digitalocean_vpc" "terraform-k8s-vpc" {
  name     = "terraform-k8s-network" # Name of the VPC
  region   = "blr1" # Bangalore
  ip_range = "172.16.0.0/16" # IP range of the VPC
}

# Create a Kubernetes cluster in the VPC
resource "digitalocean_kubernetes_cluster" "web" {
  name    = "terraform-test-k8"
  region  = "blr1" # Bangalore
  version = "1.25.4-do.0" # Latest version. Check https://cloud.digitalocean.com/kubernetes/clusters for latest version
  vpc_uuid = digitalocean_vpc.terraform-k8s-vpc.id # Use the VPC created above

  # Create a worker pool with 1 node
  node_pool {
    name       = "autoscale-worker-pool" # Name of the worker pool
    size       = "s-2vcpu-2gb" # Worker node size
    auto_scale = true # Enable auto scaling
    min_nodes  = 1 # Minimum number of nodes
    max_nodes  = 3  # Maximum number of nodes
  }
}

# Output the kubeconfig of the created cluster
output "kubernetes_cluster_output" {
  value = digitalocean_kubernetes_cluster.web.kube_config.0.raw_config # Output the raw kubeconfig
  description = "The raw kubeconfig of the created cluster" # Description of the output
  sensitive = true # Mark the output as sensitive
}

Having said that, let's look at each block.

terraform {
  required_providers {
    digitalocean = { # Name of the provider
      source = "digitalocean/digitalocean" # Source of the provider
      version = "~> 2.0" # Version of the provider
    }
  }
}

# Set the variable value in *.tfvars file
# or using -var="do_token=..." CLI option
variable "do_token" {}

# Configure the DigitalOcean Provider
provider "digitalocean" {
  token = var.do_token
}

# Create a VPC with name "terraform-k8s-network"
resource "digitalocean_vpc" "terraform-k8s-vpc" {
  name     = "terraform-k8s-network" # Name of the VPC
  region   = "blr1" # Bangalore
  ip_range = "172.16.0.0/16" # IP range of the VPC
}

The first, second, third, and fourth block (Blocks up to the creation of VPC) is the same as discussed in Part I with just different names. The first block informs Terraform to use a DigitalOcean provider to build the infrastructure. The second and third blocks are used for declaring a variable "do_token" which authenticates Terraform with your DigitalOcean account. You can obtain your own "do_token" by logging into your DO account and navigating to the API page. This variable can be set in this block itself, but the best practice is to define it on a separate file such as variable.tfvars or using -var="do_token=... in the CLI option.

# Create a Kubernetes cluster in the VPC
resource "digitalocean_kubernetes_cluster" "web" {
  name    = "terraform-test-k8"
  region  = "blr1" # Bangalore
  version = "1.25.4-do.0" # Latest version. Check https://cloud.digitalocean.com/kubernetes/clusters for latest version
  vpc_uuid = digitalocean_vpc.terraform-k8s-vpc.id # Use the VPC created above

  # Create a worker pool with 1 node
  node_pool {
    name       = "autoscale-worker-pool" # Name of the worker pool
    size       = "s-2vcpu-2gb" # Worker node size
    auto_scale = true # Enable auto scaling
    min_nodes  = 1 # Minimum number of nodes
    max_nodes  = 3  # Maximum number of nodes
  }
}

The fifth block plays a crucial role in the process, as it is here where the resources for creating a Kubernetes cluster are defined. We define name, region, version, and vpc_uuid in this block as the first four properties for our cluster.

You can put any value for name, but it is highly suggested to choose names that make sense. Good variable naming practices make engineers maintain good coding practices. Coming back to the explanation, as said earlier, the name could be anything, but the value that you can put for region and version is limited and can be found using the DigitalOcean API here. In this article, I am using blr1 as a region which is Bangalore, India, and 1.25.4-do.0 as the version, which is the latest k8s version in the DO cloud as of today.

Similarly, with vpc_uuid = digitalocean_vpc.terraform-k8s-vpc.id we are defining our VPC where the k8s cluster should be created. The value for this is set digitalocean_vpc.terraform-k8s-vpc.id because this is the same VPC we created in the fourth block as resource "digitalocean_vpc" "terraform-k8s-vpc" .

Lastly, we are defining the node_pool for our k8s cluster. As mentioned in the DO documentation, a node pool is a group of nodes (with the same configuration) within a cluster. Therefore, inside this node_pool property, we will define what kind of nodes we want in our k8s cluster. Similar to the other resource, the name property can be set to anything but the size options are limited and can be found in the DigitalOcean API. The auto_scale property informs that the cluster created from this resource can be auto-scaled from the minimum number of nodes (provided in the node_pool.min_nodes property) to the maximum number of nodes (provided in the node_pool.max_nodes property).

Moreover, there are also more optional properties or attributes that you can set while defining the DigitalOcean Kubernetes resource. You can set tags for tagging different names to your cluster, and set ha = true for enabling high availability (but note that it will cost extra money). All the other available properties that you can set up can be found by clicking here.

With these steps completed, you can now run terraform commands to create the required infrastructure and that in this case is a VPC and a k8s cluster in the DigitalOcean cloud. But remember that whenever you are executing these commands you need to be careful of where you are defining your variable (in our case the variable is do_token).

If you have specified do_token in your main.tf file itself or in another file like variables.tfvars then you should run:

$ terraform init
$ terraform plan -var-file="variable.tfvars"
$ terraform apply -var-file="variable.tfvars"
# Note: -var-file="variable.tfvars" arg is only required if you are using variable.tfvars file to store your variables

If you have not specified do_token in any file then you should run:

$ terraform init
$ terraform plan -var="do_token=..."
$ terraform apply -var="do_token=..."

Conclusion

This article provides a brief process of creating a DigitalOcean Kubernetes cluster and VPC using Terraform. The key Terraform components for defining the necessary resources were described and analyzed in detail. By following the procedures outlined in this article, one can create a Kubernetes cluster within a VPC in the DigitalOcean cloud, providing an ideal deployment environment for your web applications.

Finally, If you found this article useful, please consider sharing it with your friends and colleagues. If you have any questions or want to discuss anything related to the topic, please feel free to reach out to me on Twitter or LinkedIn, I would be happy to chat with you.

Thank you for reading.