Using Terraform to set up the AKS cluster.

Amit Gujar
5 min readApr 3, 2023

In my last blog, I wrote about creating the k8s cluster and deploying an image on the Linode platform. Today we will be doing the same thing BUT using a different technique & different platform. You see, the last time we did everything by ourselves & yes it took a little bit of extra time. Well, this time we will hire someone to do that job for us and that guy is Terraform.

Just like last time, I will be breaking down this tutorial into various steps so, it will get easy to understand for beginners. I have provided certain requirements, make sure to have those before starting the tutorial.

Tutorial Requirements :

  1. An Azure subscription.
  2. Azure CLI client.
  3. Terraform configured with Az Cli.
  4. Kubectl should be installed on your pc.

What will you learn :

  1. How to create an AKS cluster using terraform.
  2. How to deploy an application image on it.
  3. Browse your deployment.

Let’s Begin 🤩

Make a folder, it will contain all your terraform code.

Before proceeding make sure you have generated ssh-keys.

Step 1: Create a file named providers. tf and add the following code to it.

terraform {
required_version = ">= 1.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.0"
}
}
}

provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}

Step 2: Create a file named main. tf

NOTE: You can alter the image size according to your need.

resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = var.resource_group_location
}

resource "azurerm_kubernetes_cluster" "k8s" {
location = azurerm_resource_group.rg.location
name = var.cluster_name
resource_group_name = azurerm_resource_group.rg.name
dns_prefix = var.dns_prefix

default_node_pool {
name = "workernode"
vm_size = "Standard_D2_v2"
node_count = var.agent_count
}
linux_profile {
admin_username = "amitgujar"

ssh_key {
key_data = file(var.ssh_public_key)
}
}
network_profile {
network_plugin = "kubenet"
load_balancer_sku = "standard"
}
service_principal {
client_id = var.aks_service_principal_app_id
client_secret = var.aks_service_principal_client_secret
}
}

Step 3: Create a file named variables. tf

variable "resource_group_name" {
default = "k8s-demo-rg"
}

variable "resource_group_location" {
default = "centralindia"
description = "Location of the resource group."
}

variable "resource_group_name_prefix" {
default = "rg"
description = "Prefix of the resource group name"
}

variable "agent_count" {
default = 2
}

variable "aks_service_principal_app_id" {
default = ""
}

variable "aks_service_principal_client_secret" {
default = ""
}

variable "cluster_name" {
default = "myCluster"
}

variable "dns_prefix" {
default = "myCluster"
}

variable "ssh_public_key" {
default = "~/.ssh/id_rsa.pub"
}

Our terraform script is successfully created, it’s time to run them.

Step 4: Type the following command to initialize terraform

terraform init -upgrade

Once it’s done, you will see a prompt like this

Terraform Init

Step 5: Make a plan of your terraform config.

terraform plan -out main.tfplan
Terraform Apply

Step 6: Type the following command to create resources as per the plan.

terraform apply main.tfplan

You will see a success message once everything is created.

Step 7: It’s time for us to verify the resource group. Enter the following command

echo "$(terraform output resource_group_name)"

Step 8: Master Node Time.

az aks get-credentials -g k8s-demo-rg -n myCluster

Step 9: Verify if our worker nodes are ready or not.

kubectl get nodes
kubectl get nodes

Now we can conclude that our aks cluster is ready to do some action.

Step 10: Create another folder named deployment. This folder will contain the deployment code.

Step 11: Make deployment.yaml file inside the folder and add this code to it.

apiVersion: apps/v1
kind: Deployment
metadata:
name: demopods-deployment
labels:
app: demopods
spec:
replicas: 3
selector:
matchLabels:
app: demopods
template:
metadata:
labels:
app: demopods
spec:
containers:
- name: static-site
image: amitgujar/static-app:latest
imagePullPolicy: Always
ports:
- containerPort: 80

This code will pull the docker image of my basic node application and it will deploy that image on myCluster.

Step 12: Create a PowerShell file named deploy.ps1 to auto-deploy and assign a public IP to our deployment so, we can access our deployment through that IP.

NOTE: It is not important to add sleep in the script. I added that for my convenience, you can totally ignore that.

Write-Output "Deployment is started....!!!"

Start-Sleep -Seconds 3

kubectl apply -f deployment.yaml

Write-Output "Getting more information about the deployment"

kubectl describe deployment demopods-deployment

Write-Output "Listing the number of pods created by deployment"

kubectl get pods -o wide

Write-Output "Exposing the deployment...!!!"

Start-Sleep -Seconds 7

kubectl expose deployment demopods-deployment --type=LoadBalancer --port=80 --name=expose-service

Write-Output "Listing the service"

kubectl get svc

Now, before executing this check the execution policy in PowerShell. If it is restricted then you will need to change it for the script to run.

Get-ExecutionPolicy

Step 13: And action…. (run deploy.ps1)

Deploying docker image

Your output should look like this. Run the following command to check the Public IP of LB.

kubectl get svc
Exposing Deployment

Step 14: Note down this external IP. Enter the following command to see if your deployment is working successfully.

curl http://20.219.224.183
Successful Deployment on Terminal

Yes, If you need some fancy page then you can enter this address in the browser.

Successful Deployment

Step 15: Clean up your resources….

terraform destroy

Cheers 😎

Let’s summarize what we have done here.

First, we created some terraform configuration files. Then we applied that configuration to create resources. Once our cluster is created, we get connected to that cluster from our machine. Then we deployed a docker image of my sample project. We exposed our deployment to verify deployment on our machine.

The entire code is available on my GitHub.

--

--