Architecting Azure Kubernetes Service (AKS) with Terraform: From Deployment to Lifecycle Management

The intersection of container orchestration and Infrastructure as Code (IaC) is most prominently realized in the combination of Azure Kubernetes Service (AKS) and HashiCorp Terraform. For DevOps engineers and cloud architects, managing a Kubernetes cluster manually through the Azure Portal is inefficient and prone to configuration drift. Terraform provides a declarative approach to provisioning, ensuring that the underlying virtual machine scale sets, networking, and identity management for an AKS cluster are reproducible, version-controlled, and scalable.

As the ecosystem evolves, Microsoft has transitioned toward Azure Verified Modules (AVM), which are pre-defined, reusable IaC modules maintained by Microsoft to ensure production-ready deployments that adhere to institutional best practices and compliance standards. This transition represents a shift from simple resource deployment to the implementation of enterprise-grade architectural patterns.

The Evolution of AKS Terraform Modules

Historically, the community and Microsoft relied on generic modules to deploy AKS. However, there is a critical transition currently occurring in the module landscape. The legacy terraform-azurerm-aks module is being retired. While bug fixes continue through April, new features are no longer being accepted, with official retirement scheduled for May.

Engineers are strongly advised to migrate to the new Azure Verified Module (AVM) located at Azure/avm-res-containerservice-managedcluster/azurerm. This migration is not merely a change in source path but an upgrade to a framework designed for reliability and consistency.

For those utilizing specific versions of the AzureRM provider, compatibility is maintained through source adjustments. Specifically, users of AzureRM v4 can continue to utilize the legacy module by setting the source to Azure/aks/azurerm//v4. It is imperative to note that major version updates (for example, moving from version 6.8.0 to 7.0.0) often contain breaking changes. These updates necessitate a thorough review of the changelog and migration guides to adjust Terraform code and prevent infrastructure instability during the upgrade process.

Essential Prerequisites and Environment Setup

Before initiating the deployment of an AKS cluster via Terraform, several local and cloud-based prerequisites must be satisfied to ensure a seamless authentication and configuration flow.

Required Tooling and Accounts

The following table outlines the mandatory components required for a local development environment to successfully provision and manage AKS resources.

Requirement Purpose Installation/Verification Command
Azure Account Cloud subscription for resource hosting az login
Azure CLI Command-line interface for Azure management az --version
kubectl Kubernetes command-line tool for cluster interaction az aks install-cli
Terraform IaC engine for resource provisioning terraform -version

Subscription Context and Authentication

Once the Azure CLI is installed, the user must authenticate and set the active subscription context to avoid deploying resources into the wrong environment. This is achieved using the az account set command:

bash az account set --subscription "00000000-0000-0000-0000-000000000000"

Core Terraform Configuration Components

A robust Terraform project for AKS is typically decomposed into several files to maintain separation of concerns. This modularity allows for easier debugging and updates to specific parts of the infrastructure without risking the entire stack.

The Main Configuration (main.tf)

The main.tf file is the heart of the deployment, defining the azurerm_kubernetes_cluster resource. A production-ready configuration includes specific details regarding the node pool, Kubernetes version, and identity management.

For example, a basic AKS resource block includes the following parameters:
- dnsprefix: A unique prefix for the Kubernetes API server.
- kubernetesversion: Specifies the version of Kubernetes to deploy (e.g., "1.34").
- defaultnodepool: Defines the compute capacity, including the number of VMs (node_count) and the VM size (e.g., "StandardD2v4").
- osdisksizegb: The size of the OS disk for the nodes (e.g., 30 GB).
- rolebasedaccesscontrol_enabled: A boolean to enable Azure RBAC for granular permission management.

Identity and Access Management

Authentication for the AKS cluster can be handled in two primary ways within Terraform:

  1. Service Principal: This requires providing a client_id (appId) and client_secret (password) via the service_principal block.
  2. System-Assigned Managed Identity: If neither a client_id nor a client_secret is assigned in the configuration, Azure automatically creates a SystemAssigned identity for the cluster. This is generally preferred for security as it eliminates the need to manage secrets manually.

Supporting Configuration Files

To ensure the environment is flexible and output-driven, the following files are utilized:
- providers.tf: Configures the azurerm provider version and required settings.
- variables.tf: Declares input variables such as appId and password, allowing the same code to be used across different environments (Dev, Stage, Prod).
- outputs.tf: Defines the data to be returned after a successful apply, such as the cluster name or the kube_config.
- ssh.tf: Handles the generation and assignment of SSH keys for node access.

The Deployment Workflow

Deploying an AKS cluster involves a standardized sequence of Terraform commands. This lifecycle ensures that changes are planned and validated before they are permanently applied to the Azure cloud.

Provisioning Steps

The following sequence describes the standard execution flow:

  1. Initialization: terraform init downloads the necessary Azure providers and initializes the backend.
  2. Validation: terraform validate checks the syntax and internal consistency of the configuration files. It is common to see warnings regarding deprecated arguments when using AVMs; these typically do not prevent deployment.
  3. Planning: terraform plan generates an execution plan, detailing exactly which resources will be created, modified, or destroyed.
  4. Application: terraform apply executes the plan and provisions the resources in the Azure subscription.

Alternative Provisioning with Azure Developer CLI (azd)

For developers using the Azure Developer CLI (azd), the provisioning process is further streamlined. The azd tool automatically runs preprovision and postprovision hooks. Within an Azure Developer template, the Terraform code resides in the /infra/terraform folder. When azd is executed, it invokes terraform apply as part of its provisioning step, typically providing a summary such as "Plan: 5 to add, 0 to change, 0 to destroy."

Post-Deployment Cluster Interaction

Once Terraform signals a successful deployment, the operator must transition from the IaC layer to the Kubernetes orchestration layer.

Configuring Access

To interact with the newly created cluster, the kubectl CLI must be configured with the correct credentials. This is done using the Azure CLI:

bash az aks get-credentials --resource-group <resource-group> --name <cluster-name>

Alternatively, the Kubernetes configuration can be extracted directly from the Terraform state:

bash echo "$(terraform output kube_config)" > ./azurek8s

Technical Note: When extracting kube_config via the command line, it is critical to verify that no ASCII EOT characters (represented as << EOT at the beginning and EOT at the end) were inadvertently added to the file. If present, these must be removed for kubectl to function correctly.

Verifying Cluster Health

Verification is performed using standard kubectl commands to ensure the control plane and worker nodes are communicating:

  • kubectl get nodes: Returns a list of all nodes in the cluster and their status.
  • kubectl get pods: Checks the status of deployed pods.
  • kubectl config set-context --current --namespace=pets: Sets the current active namespace (e.g., a "pets" demo namespace) for subsequent commands.

Production-Grade Architecture Patterns

The Azure Verified Modules (AVM) introduce specific architectural patterns that distinguish a "learning" cluster from a "production" cluster.

High Availability and Zone Alignment

A critical feature of the AVM-based AKS deployment is the implementation of zone-aligned node pools. Instead of a single monolithic pool, the AVM implements availability zones by using a single node pool for each zone, combined with the cluster autoscaler. This ensures that if a single Azure availability zone fails, the application remains available in other zones.

Sample Application Architecture

In a typical enterprise deployment, the AKS cluster hosts a microservices architecture. A common reference pattern includes:

  • Store Front: A customer-facing web application.
  • Product Service: A backend service managing product data.
  • Order Service: A service handling the order placement logic.
  • Rabbit MQ: A message queue used to decouple the order service from other processes.

Critical Infrastructure Warning: For production environments, it is strongly recommended against running stateful containers, such as Rabbit MQ, without implementing persistent storage. Using the default ephemeral storage of an AKS node can lead to catastrophic data loss during pod restarts or node upgrades.

Technical Specification Summary

The following table summarizes the key configuration values and commands used throughout the AKS Terraform lifecycle.

Component Detail/Command Context
Default VM Size StandardD2v4 Compute specification for nodes
OS Disk Size 30 GB Standard boot disk allocation
K8s Version 1.34 Targeted Kubernetes release
Init Command terraform init Provider initialization
Plan Command terraform plan Resource delta analysis
Apply Command terraform apply Resource instantiation
Get Credentials az aks get-credentials Kubeconfig configuration
Verify Nodes kubectl get nodes Connectivity verification
Cluster List az aks list Azure resource discovery

Conclusion

Deploying Azure Kubernetes Service via Terraform represents a sophisticated balance between cloud-native orchestration and rigorous infrastructure management. The shift toward Azure Verified Modules (AVM) underscores the importance of using standardized, Microsoft-maintained patterns to ensure that clusters are not only functional but production-ready, featuring zone alignment and autoscaling capabilities.

The operational flow—transitioning from terraform init and plan to terraform apply, and finally to az aks get-credentials—creates a clear pipeline from code to a live environment. However, the transition to AVM and the retirement of legacy modules highlight the dynamic nature of the Azure ecosystem. Engineers must prioritize the migration to Azure/avm-res-containerservice-managedcluster/azurerm and maintain a strict cadence of reviewing changelogs to avoid breaking changes during version upgrades.

Ultimately, the success of an AKS deployment depends on the correct configuration of identity (SystemAssigned vs. Service Principal), the strategic use of node pools across availability zones, and the cautious deployment of stateful services. By adhering to these technical standards, organizations can achieve a scalable, resilient Kubernetes environment that benefits from the full power of Azure's global infrastructure.

Sources

  1. GitHub - Azure/terraform-azurerm-aks
  2. Microsoft Learn - Deploy AKS Cluster Terraform Verified Module
  3. Microsoft Docs - Quick Kubernetes Deploy Terraform
  4. HashiCorp Developer - Provision AKS Cluster

Related Posts