In the world of container orchestration and cloud-native applications, Azure Kubernetes Service (AKS) stands as a powerful platform for managing and scaling containerized workloads seamlessly. To automate the deployment of your Kubernetes clusters on Microsoft Azure, Terraform emerges as the go-to tool. In this article, we will embark on a journey to explore the art of creating an Azure AKS cluster with Terraform
Link to Github code repo here
Prerequisites:
- Azure Subscription: You should have an active Microsoft Azure subscription. If you don't have one, you can sign up for a free trial here
- Terraform Installed: Ensure that Terraform is installed on your local development machine. You can download it from the official website here
- Azure CLI Installed: Install the Azure CLI, which is a command-line tool for managing Azure resources. You can download it from here
- Azure Service Principal: You'll need an Azure service principal with the appropriate permissions to create and manage resources. You can create one using the Azure CLI or Azure Portal
- Azure CLI Authentication: Authenticate the Azure CLI using your service principal credentials
Provider.tf
Provider.tf file in a Terraform configuration is used to define and configure the providers that Terraform should use for managing resources in a specific cloud or infrastructure platform. Providers are responsible for translating Terraform configurations into API calls and actions on the target platform
Let's create ours in a project folder with the following content:
provider "azurerm" {
features {}
}
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
}
}
- Provider block specifies the Azure provider
azurerm
features {}
is an empty configuration block. In this example, no specific features are enabled or configured, but you can specify provider-specific features within this block if needed.
terraform
block is used to configure global settings for your Terraform configuration.
required_providers
specifies the providers required for this configuration. We declare that theazurerm
provider is requiredsource
specifies that the provider should be fetched from the HashiCorp provider registry
It's a foundational part of our Terraform configuration, ensuring that Terraform knows which provider to use when creating and managing Azure resources
Main.tf
In our project folder, next step is to create a main.tf
file, which serves as the foundation for our Terraform configuration. In this configuration, our initial task is to create a resource group that will house our future AKS (Azure Kubernetes Service) cluster.
resource "azurerm_resource_group" "aks-rg" {
name = var.resource_group_name
location = var.location
}
Now let's set up a network configuration within an Azure resource group, defining the address space and subnet for the virtual network. In order to ensure that the network module is created after the Azure resource group is created, we would specify the depends_on attribute.
module "network" {
source = "Azure/network/azurerm"
resource_group_name = azurerm_resource_group.aks-rg.name
address_spaces = ["10.20.0.0/16"]
subnet_prefixes = ["10.20.0.0/21"]
subnet_names = ["subnet1"]
use_for_each = true
depends_on = [azurerm_resource_group.aks-rg]
}
Our next step involves declaring a module to set up the AKS cluster. You can refer to the documentation link for detailed information
module "aks" {
source = "Azure/aks/azurerm"
version = "7.4.0"
prefix = "dev"
cluster_name = var.cluster_name
resource_group_name = azurerm_resource_group.aks-rg.name
location = var.location
agents_pool_name = "testpool"
agents_availability_zones = [1, 2]
agents_size = var.vm_size
orchestrator_version = var.orchestrator_version
enable_auto_scaling = true
agents_min_count = 1
agents_max_count = 6
agents_max_pods = 100
vnet_subnet_id = module.network.vnet_subnets[0]
network_plugin = "azure"
network_policy = "calico"
rbac_aad = false
private_cluster_enabled = false
node_pools = {
pool1 = {
name = "pool1"
vm_size = var.vm_size
enable_auto_scaling = true
node_count = 1
min_count = 1
max_count = 5
vnet_subnet_id = module.network.vnet_subnets[0]
orchestrator_version = var.orchestrator_version
mode = "User"
}
}
depends_on = [azurerm_resource_group.aks-rg, module.network]
}
Let's define couple of configuration options for the AKS cluster, including:
prefix
: A prefix used for naming resources within the cluster.cluster_name
: The name of the AKS cluster, which is defined as a variable (var.cluster_name).resource_group_name
: Specifies the name of the Azure resource group where the cluster will be created.location
: Specifies the Azure region where the cluster will be deployed.agents_pool_name
: The name of the default agent pool.agents_availability_zones
: A list of Azure availability zones for the agent nodes.agents_size
: The size of the agent VMs.orchestrator_version
: The version of Kubernetes to use.enable_auto_scaling
: Enables auto-scaling for the agent pool.agents_min_count
andagents_max_count
: Minimum and maximum node counts for the default agent pool.agents_max_pods
: Maximum pods per node in default node pool.vnet_subnet_id
: The ID of the virtual network subnet where the AKS cluster should be placed, referencing the subnet created in the module.network module.network_plugin
andnetwork_policy
: Network configuration settings.rbac_aad
: Specifies whether Azure Active Directory (AAD) integration is enabled.private_cluster_enabled
: Specifies whether the AKS cluster is private.node_pools
: Defines additional node pools within the AKS cluster.
Please note in order to avoid any errors
orchestrator_version
should be the same, or you can leave it as default - it will create lates version
Variables.tf
Here we would define all our variables:
variable "resource_group_name" {
type = string
description = "RG name in Azure"
default = "test"
}
variable "location" {
type = string
description = "Resources location in Azure"
default = "eastus"
}
variable "cluster_name" {
type = string
description = "AKS name in Azure"
default = "test-aks"
}
variable "orchestrator_version" {
type = string
description = "Kubernetes version"
default = "1.26.6"
}
variable "vm_size" {
type = string
description = "Size of the agent VMs"
default = "Standard_DS3_v2"
}
Final Step - Deployment
In order to initialize terraform and download modules run:
`terraform init`
You can also check which resources terraform is planning to create by running:
terraform plan
To provision resources run:
terraform apply
After terraform is applied you can connect to your AKS Cluster:
az aks get-credentials -n <YOUR_CLUSTER_NAME> -g <RESOURCE_GROUP_NAME>
You can find source code in our Github repo