Deploying a Linode Kubernetes Engine Cluster Using Terraform

Updated by Linode Contributed by Linode

Contribute on GitHub

Report an Issue | View File | Edit File

Marquee image for How to Deploy a Linode Kubernetes Engine Cluster Using Terraform

What is the Linode Kubernetes Engine (LKE)?

The Linode Kubernetes Engine (LKE) is a fully-managed container orchestration engine for deploying and managing containerized applications and workloads. LKE combines Linode’s ease of use and simple pricing with the infrastructure efficiency of Kubernetes. When you deploy a LKE cluster, you receive a Kubernetes Master at no additional cost; you only pay for the Linodes (worker nodes), NodeBalancers (load balancers), and Block Storage Volumes. Your LKE Cluster’s Master node runs the Kubernetes control plane processes – including the API, scheduler, and resource controllers.

In this Guide

This guide will walk you through the steps needed to deploy a Kubernetes cluster using LKE and the popular infrastructure as code (IaC) tool, Terraform. Throughout the guide you will:

Before you Begin

  1. Create a personal access token for Linode’s API v4. Follow the Getting Started with the Linode API to get a token. You will need a token to be able to create Linode resources using Terraform.

    Note
    Ensure that your token has, at minimum, Read/Write permissions for Linodes, Kubernetes, NodeBalancers, and Volumes.
  2. Review the A Beginner’s Guide to Terraform to familiarize yourself with Terraform concepts if you have not used the tool before. This guide assumes familiarity with Terraform and its native HCL syntax.

Prepare your Local Environment

Install Terraform

Install Terraform on your computer by following the Install Terraform section of our Use Terraform to Provision Linode Environments guide.

Install kubectl

macOS:

Install via Homebrew:

brew install kubernetes-cli

If you don’t have Homebrew installed, visit the Homebrew home page for instructions. Alternatively, you can manually install the binary; visit the Kubernetes documentation for instructions.

Linux:

  1. Download the latest kubectl release:

    curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
    
  2. Make the downloaded file executable:

    chmod +x ./kubectl
    
  3. Move the command into your PATH:

    sudo mv ./kubectl /usr/local/bin/kubectl
    
Note
You can also install kubectl via your package manager; visit the Kubernetes documentation for instructions.

Windows:

Visit the Kubernetes documentation for a link to the most recent Windows release.

Create your Terraform Configuration Files

In this section, you will create Terraform configuration files that define the resources needed to create a Kubernetes cluster. You will create a main.tf file to store your resource declarations, a variables.tf file to store your input variable definitions, and a terraform.tfvars file to assign values to your input variables. Setting up your Terraform project in this way will allow you to reuse your configuration files to deploy more Kubernetes clusters, if desired.

Create your Resource Configuration File

Terraform defines the elements of your Linode infrastructure inside of configuration files. Terraform refers to these infrastructure elements as resources. Once you declare your Terraform configuration, you then apply it, which results in the creation of those resources on the Linode platform. The Linode Provider for Terraform exposes the Linode resources you will need to deploy a Kubernetes cluster using LKE.

  1. Navigate to the directory where you installed Terraform. Replace ~/terraform with the location of your installation.

    cd ~/terraform
    
  2. Create a new directory to store your LKE cluster’s Terraform configurations. Replace lke-cluster with your preferred directory name.

    mkdir lke-cluster
    
  3. Using the text editor of your choice, create your cluster’s main configuration file named main.tf which will store your resource definitions. Add the following contents to the file.

    ~/terraform/lke-cluster/main.tf
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
    //Use the Linode Provider
    provider "linode" {
      token = var.token
    }
    
    //Use the linode_lke_cluster resource to create
    //a Kubernetes cluster
    resource "linode_lke_cluster" "foobar" {
        k8s_version = var.k8s_version
        label = var.label
        region = var.region
        tags = var.tags
    
        dynamic "pool" {
            for_each = var.pools
            content {
                type  = pool.value["type"]
                count = pool.value["count"]
            }
        }
    }
    
    //Export this cluster's attributes
    output "kubeconfig" {
       value = linode_lke_cluster.foobar.kubeconfig
    }
    
    output "api_endpoints" {
       value = linode_lke_cluster.foobar.api_endpoints
    }
    
    output "status" {
       value = linode_lke_cluster.foobar.status
    }
    
    output "id" {
       value = linode_lke_cluster.foobar.id
    }
    
    output "pool" {
       value = linode_lke_cluster.foobar.pool
    }
        

    This file contains your cluster’s main configuration arguments and output variables. In this example, you make use of Terraform’s input variables so that your main.tf configuration can be easily reused across different clusters.

    Variables and their values will be created in separate files later on in this guide. Using separate files for variable declaration allows you to avoid hard-coding values into your resources. This strategy can help you reuse, share, and version control your Terraform configurations.

    This configuration file uses the Linode provider to create a Kubernetes cluster. All arguments within the linode_lke_cluster.foobar resource are required, except for tags. The pool argument accepts a list of pool objects. In order to read their input variable values, the configuration file makes use of Terraform’s dynamic blocks. Finally, output values are declared in order to capture your cluster’s attribute values that will be returned to Terraform after creating your cluster.

    Note

    You can set any output value as being sensitive in order to prevent Terraform from printing its value to your terminal after running terraform apply. For example, to set the kubeconfig output value as sensitive, update its output block in the following way:

    ~/terraform/lke-cluster/main.tf
    1
    2
    3
    4
    5
    6
    
    ...
    output "kubeconfig" {
       value = linode_lke_cluster.foobar.kubeconfig
       sensitive = true
    }
    ...

    See Terraform’s output value documentation for more details on the behavior of the sensitive argument.

    Note
    For a complete linode_lke_cluster resource argument reference, see the Linode Provider Terraform documentation. You can update the main.tf file to include any additional arguments you would like to use.

Define your Input Variables

You are now ready to define the input variables that were referenced in your main.tf file.

  1. Create a new file named variables.tf in the same directory as your main.tf file. Add the following contents to the file:

    ~/terraform/lke-cluster/variables.tf
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
        variable "token" {
          description = "Your Linode API Personal Access Token. (required)"
        }
    
        variable "k8s_version" {
          description = "The Kubernetes version to use for this cluster. (required)"
          default = "1.17"
        }
    
        variable "label" {
          description = "The unique label to assign to this cluster. (required)"
          default = "default-lke-cluster"
        }
    
        variable "region" {
          description = "The region where your cluster will be located. (required)"
          default = "us-east"
        }
    
        variable "tags" {
          description = "Tags to apply to your cluster for organizational purposes. (optional)"
          type = list(string)
          default = ["testing"]
        }
    
        variable "pools" {
          description = "The Node Pool specifications for the Kubernetes cluster. (required)"
          type = list(object({
            type = string
            count = number
          }))
          default = [
            {
              type = "g6-standard-4"
              count = 3
            },
            {
              type = "g6-standard-8"
              count = 3
            }
          ]
        }
        

    This file describes each variable and provides them with default values. You can update the file with your own preferred default values.

Assign Values to your Input Variables

You will now need to define the values you would like to use in order to create your Kubernetes cluster. These values are stored in a separate file named terraform.tfvars. This file should be the only file that requires updating when reusing the files created in this guide to deploy a new Kubernetes cluster or to add a new node pool to the cluster.

  1. Create a new file named terraform.tfvars to provide values for all the input variables declared in the previous section.

    Note
    If you leave out a variable value in this file, Terraform will use the variable’s default value that you provided in your variables.tf file.
    $~/terraform/lke-cluster/terraform.tfvars
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    label = "example-lke-cluster"
    k8s_version = "1.17"
    region = "us-west"
    pools = [
      {
        type : "g6-standard-2"
        count : 3
      }
    ]
          

    Terraform will use the values in this file to create a new Kubernetes cluster with one node pool that contains three 4 GB nodes. The cluster will be located in the us-west data center (Dallas, Texas, USA). Each node in the cluster’s node pool will use Kubernetes version 1.17 and the cluster will be named example-lke-cluster. You can replace any of the values in this file with your own preferred cluster configurations.

Deploy your Kubernetes Cluster

Now that all your Terraform configuration files are ready, you can deploy your Kubernetes cluster.

  1. Ensure that you are in your lke-cluster project directory which should contain all of your Terraform configuration files. If you followed the naming conventions used in this guide, your project directory will be ~/terraform/lke-cluster.

    cd ~/terraform/lke-cluster
    
  2. Install the Linode Provider to your Terraform project directory. Whenever a new provider is used in a Terraform configuration, it must be initialized before you can create resources with it.

    terraform init
    

    You will see a message that confirms that the Linode provider plugins have been successfully initialized.

  3. Export your API token to an environment variable. Terraform environment variables have the prefix TF_VAR_ and are supplied at the command line. This method is preferable over storing your token in a plain text file. Replace the example’s token value with your own.

    export TF_VAR_token=70a1416a9.....d182041e1c6bd2c40eebd
    
    Caution
    This method commits the environment variable to your shell’s history, so take care when using this method.
  4. View your Terraform’s execution plan before deploying your infrastructure. This command won’t take any actions or make any changes on your Linode account. It will provide a report displaying all the resources that will be created or modified when the plan is executed.

    terraform plan \
    -var-file="terraform.tfvars"
    
  5. Apply your Terraform configurations to deploy your Kubernetes cluster.

    terraform apply \
    -var-file="terraform.tfvars"
    

    Terraform will begin to create the resources you’ve defined throughout this guide. This process will take several minutes to complete. Once the cluster has been successfully created the output will include a success message and the values that you exposed as output when creating your main.tf file (the example output has been truncated for brevity).

      
    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
    
    Outputs:
    
    api_endpoints = [
      "https://91132f3d-fd20-4a70-a171-06ddec5d9c4d.us-west-2.linodelke.net:443",
      "https://91132f3d-fd20-4a70-a171-06ddec5d9c4d.us-west-2.linodelke.net:6443",
      "https://192.0.2.0:443",
      "https://192.0.2.0:6443",
    ]
    ...
              
    

Connect to your LKE Cluster

Now that your Kubernetes cluster is deployed, you can use kubectl to connect to it and begin defining your workload. In this section, you will access your cluster’s kubeconfig and use it to connect to your cluster with kubectl.

  1. Use Terraform to access your cluster’s kubeconfig, decode its contents, and save them to a file. Terraform returns a base64 encoded string (a useful format for automated pipelines) representing your kubeconfig. Replace lke-cluster-config.yaml with your preferred file name.

    export KUBE_VAR=`terraform output kubeconfig` && echo $KUBE_VAR | base64 -d > lke-cluster-config.yaml
    
    Note

    Depending on your local operating system, to decode the kubeconfig’s base64 format, you may need to replace base64 -d with base64 -D. To determine which base64 option to use, issue the following command:

    base64 --help
    
  2. Add the kubeconfig file to your $KUBECONFIG environment variable. This will give kubectl access to your cluster’s kubeconfig file.

    export KUBECONFIG=lke-cluster-config.yaml
    
  3. Verify that your cluster is selected as kubectl’s current context:

    kubectl config get-contexts
    
  4. View all nodes in your Kubernetes cluster using kubectl:

    kubectl get nodes
    

    Your output will resemble the following example, but will vary depending on your own cluster’s configurations.

      
    NAME                        STATUS   ROLES    AGE   VERSION
    lke4377-5673-5eb331ac7f89   Ready       17h   v1.17.0
    lke4377-5673-5eb331acab1d   Ready       17h   v1.17.0
    lke4377-5673-5eb331acd6c2   Ready       17h   v1.17.0
        
    

    Now that you are connected to your LKE cluster, you can begin using kubectl to deploy applications, inspect and manage cluster resources, and view logs.

Destroy your Kubernetes Cluster (optional)

Terraform includes a destroy command to remove resources managed by Terraform.

  1. Run the plan command with the -destroy option to verify which resources will be destroyed.

    terraform plan -destroy
    

    Follow the prompt to enter your Linode API v4 access token and review the report to ensure the resources you expect to be destroyed are listed.

  2. Destroy the resources outlined in the above command.

    terraform destroy
    

    Follow the prompt to enter your Linode API v4 access token and type in yes when prompted to destroy your Kubernetes cluster.

More Information

You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

Join our Community

Find answers, ask questions, and help others.

This guide is published under a CC BY-ND 4.0 license.