Blog Post

ITOps Talk Blog
4 MIN READ

Deploying a Windows AKS cluster with Terraform

ViniciusApolinario's avatar
Apr 19, 2023

Terraform is one of the most popular tools today for cloud management. As an Infrastructure as Code (IaC) tool, it allows you to declaratively provision infrastructure on cloud providers such as Azure. In this blog post, we will cover how to deploy an AKS cluster with Windows nodes, so you can deploy Windows based applications into it.

 

Terraform pre-requisites

Terraform has multiple providers, which includes Azure and its resources. The azurerm provider, allows you to extend the Terraform capabilities for Azure resources. You can deploy Resource Groups, as well as many Azure resources from Terraform manifests.

Azure Kubernetes Service (AKS) is also available as a managed resource for Terraform manifests. The trick is that you need to specify a few important things when deploying an AKS cluster with Windows nodes. Before we get started, let’s make sure your environment has the necessary components for you to deploy the AKS cluster:

First and foremost, you need AZ CLI running, so make sure you have it installed and updated.

Next, we need to install the terraform CLI. You can follow the instructions on the Terraform docs page. Ultimately, I believe the most straightforward way to get it running is by installing it via Chocolatey:

 

choco install terraform

 

Now you need to authenticate the Terraform CLI against your Azure subscription. While the documentation from both Terraform and Azure inform that you can use the az login command to authenticate, my tests proved it’s not currently working as reported on GitHub issues. To work around this, make sure you follow the documentation to create a Service Principal to authenticate Terraform.

With the above in place, you should have everything ready to deploy your Terraform manifest.

 

Terraform manifest for Windows on AKS

Before we go any further, I want to clarify that the example below is nothing more than that: an example of a Terraform manifest. It contains a few things that you do not want to use in production, such as passing on Service Principal ID and password in plain text, as well as hardcoded configuration, and usernames and passwords. Since this sample is intended for demo and training purposes, it’s provided as is, but please do not use this in production. With that said, let’s take a look at what a Terraform manifest looks like for Windows on AKS:

 

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=3.0.0"
    }
  }
}

provider "azurerm" {
  features {}

  subscription_id   = "<azure_subscription_id>"
  tenant_id         = "<azure_subscription_tenant_id>"
  client_id         = "<service_principal_appid>"
  client_secret     = "<service_principal_password>"
}

resource "azurerm_resource_group" "rg" {
  name     = var.resource_group
  location = var.location
}

resource "azurerm_virtual_network" "vnet" {
  name                = "testvnet"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  address_space       = ["10.1.0.0/16"]

  subnet {
    name           = "subnet1"
    address_prefix = "10.1.1.0/24"
  }
}

resource "azurerm_kubernetes_cluster" "aks" {
  name                = "ContosoCluster"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  dns_prefix = "contosocluster"

  default_node_pool {
    name           = "lin"
    node_count     = var.node_count_linux
    vm_size        = "Standard_D2_v2"
    vnet_subnet_id = element(tolist(azurerm_virtual_network.vnet.subnet),0).id
  }

  windows_profile {
    admin_username = "Microsoft"
    admin_password = "M1cr0s0ft@2023"
  }
  
  network_profile {
    network_plugin = "azure"
  }

  identity {
    type = "SystemAssigned"
  }
}

resource "azurerm_kubernetes_cluster_node_pool" "win" {
  name                  = "wspool"
  kubernetes_cluster_id = azurerm_kubernetes_cluster.aks.id
  vm_size               = "Standard_D4s_v3"
  node_count            = var.node_count_windows
  os_type               = "Windows"
}

output "kube_config" {
  value = azurerm_kubernetes_cluster.aks.kube_config_raw
  sensitive = true
}

 

The file above should be named main.tf. Along with this file, you should have another one called variables.tf:

 

variable "resource_group" {
    type = string
    description = "Resource group name"
    default = "TestRG"
}

variable "location" {
    type = string
    description = "RG and resources location"
    default = "West US"
}

variable "node_count_linux" {
    type = number
    description = "Linux nodes count"
    default = 1
}

variable "node_count_windows" {
    type = number
    description = "Windows nodes count"
    default = 2
}

 

The main.tf file is the body of your deployment. It contains what Terraform is going to deploy. The variables.tf file contains a few parameters that are easier when set up on a separate file. If you need change the name of the resource group you want to use, you can do that just once. You could do that for other parameters as well.

 

Deploying Windows on AKS with the Terraform manifest

With the above in place, let’s open a PowerShell session and run the following:

 

terraform init
terraform apply -auto-approve

 

Notice that you don’t need to authenticate, because you are using a Service Principal. After a while, you should see the success output from Terraform and the resources created in Azure.

 

kubectl get node -o wide
NAME                          STATUS   ROLES   AGE     VERSION    INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION     CONTAINER-RUNTIME
aks-lin-11535342-vmss000000   Ready    agent   8m52s   v1.24.10   10.1.1.4      <none>        Ubuntu 18.04.6 LTS               5.4.0-1105-azure   containerd://1.6.18+azure-1
akswspool000000               Ready    agent   4m4s    v1.24.10   10.1.1.33     <none>        Windows Server 2019 Datacenter   10.0.17763.4252    containerd://1.6.14+azure
akswspool000001               Ready    agent   4m5s    v1.24.10   10.1.1.64     <none>        Windows Server 2019 Datacenter   10.0.17763.4252    containerd://1.6.14+azure

 

 

Conclusion

This was a very simple way to deploy an AKS cluster with Windows nodes. From here you can deploy Windows container applications and run the cluster normally.

In future blog posts, we will cover more advanced configuration of Terraform and Windows on AKS. Keep an eye out for it and let us know in the comments what you think!

Finally, if you’d like to reuse or collaborate on this sample, check out our GitHub repo!

Updated Apr 18, 2023
Version 1.0
  • thx1200's avatar
    thx1200
    Bronze Contributor

    You should use winget instead of chocolatey.  😉  Dogfood.