Deploying a Linode Kubernetes Engine Cluster Using Terraform
Updated by Linode Contributed by Linode
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:
- Prepare your local environment by installing Terraform and kubectl.
- Create reusable Terraform configuration files to define your Kubernetes cluster’s resources.
- Optionally, you will destroy the cluster you create using Terraform.
Before you Begin
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.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:
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
Make the downloaded file executable:
chmod +x ./kubectl
Move the command into your PATH:
sudo mv ./kubectl /usr/local/bin/kubectl
NoteYou 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.
Navigate to the directory where you installed Terraform. Replace
~/terraform
with the location of your installation.cd ~/terraform
Create a new directory to store your LKE cluster’s Terraform configurations. Replace
lke-cluster
with your preferred directory name.mkdir lke-cluster
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 fortags
. Thepool
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 thekubeconfig
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 completelinode_lke_cluster
resource argument reference, see the Linode Provider Terraform documentation. You can update themain.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.
Create a new file named
variables.tf
in the same directory as yourmain.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.
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 yourvariables.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 version1.17
and the cluster will be namedexample-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.
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
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.
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.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"
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.
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
withbase64 -D
. To determine whichbase64
option to use, issue the following command:base64 --help
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
Verify that your cluster is selected as kubectl’s current context:
kubectl config get-contexts
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.
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.
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.
- Setting Up a Private Docker Registry with Linode Kubernetes Engine and Object Storage
- Deploying a Static Site on Linode Kubernetes Engine
- Linode Provider Terraform Documentation
Join our Community
Find answers, ask questions, and help others.
This guide is published under a CC BY-ND 4.0 license.