From a9978f6568703d89837456e605c9a53989de3a23 Mon Sep 17 00:00:00 2001 From: RebeccaCalixte <262454636+Rebecca-Calixte@users.noreply.github.com> Date: Thu, 13 Aug 2026 13:35:29 -0400 Subject: [PATCH 01/12] Add AKS ALB Controller quickstart --- quickstart/101-aks-alb-controller/README.md | 142 ++++++++++++++++++++ quickstart/101-aks-alb-controller/main.tf | 93 +++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 quickstart/101-aks-alb-controller/README.md create mode 100644 quickstart/101-aks-alb-controller/main.tf diff --git a/quickstart/101-aks-alb-controller/README.md b/quickstart/101-aks-alb-controller/README.md new file mode 100644 index 000000000..165cd7c4e --- /dev/null +++ b/quickstart/101-aks-alb-controller/README.md @@ -0,0 +1,142 @@ +# Deploy Application Gateway for Containers ALB Controller on AKS + +This template deploys an Azure Kubernetes Service (AKS) cluster with the Application Gateway for Containers ALB Controller add-on enabled. It also installs the Gateway API implementation required to use Gateway API resources with the add-on. + +The AzureRM provider does not currently expose the AKS `ingressProfile` configuration. This sample uses the AzAPI provider to apply the preview `ingressProfile` settings after creating the AKS cluster. + +## Prerequisites + +- An Azure subscription. To create one, see [Create an Azure account](https://azure.microsoft.com/free/). +- Terraform `>= 1.6.0` installed. +- Azure CLI installed and authenticated with `az login`. +- `kubectl` installed. +- Permission to create AKS resources and assign the required roles. +- The `Microsoft.ContainerService` and `Microsoft.ServiceNetworking` resource providers registered in the subscription. +- A supported Azure region for Application Gateway for Containers. +- An AKS cluster using Azure CNI or Azure CNI Overlay. AKS Automatic clusters are not supported for this scenario. + +## Terraform resource types + +- [random_pet](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) +- [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) +- [azurerm_kubernetes_cluster](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster) +- [azapi_update_resource](https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/update_resource) + +## Example + +Initialize, format, and validate the configuration: + +```console +terraform init +terraform fmt +terraform validate +``` + +Review and apply the configuration: + +```console +terraform plan +terraform apply +``` + +The Terraform outputs include the resource group name, AKS cluster name, and AKS cluster resource ID. + +The cluster is configured with Azure CNI networking, OIDC issuer, workload identity, and a system-assigned managed identity. The AzAPI update enables the Application Gateway for Containers ALB Controller through the AKS `ingressProfile` and installs the Gateway API implementation: + +```hcl +ingressProfile = { + applicationLoadBalancer = { + enabled = true + } + gatewayAPI = { + installation = "Standard" + } +} +``` + +## Update an existing cluster + +For an existing AKS cluster, use data sources to reference the cluster and apply the same `ingressProfile` update: + +```hcl +data "azurerm_kubernetes_cluster" "existing" { + name = "myAKSCluster" + resource_group_name = "myResourceGroup" +} + +resource "azapi_update_resource" "enable_alb_existing" { + type = "Microsoft.ContainerService/managedClusters@2025-09-02-preview" + resource_id = data.azurerm_kubernetes_cluster.existing.id + body = { + properties = { + oidcIssuerProfile = { + enabled = true + } + securityProfile = { + workloadIdentity = { + enabled = true + } + } + ingressProfile = { + applicationLoadBalancer = { + enabled = true + } + gatewayAPI = { + installation = "Standard" + } + } + } + } +} +``` + +Apply the update: + +```console +terraform apply +``` + +## Verify the installation + +Retrieve the cluster credentials and check the system namespace: + +```console +az aks get-credentials --name --resource-group +kubectl get pods -n kube-system +``` + +Verify that the GatewayClass is available: + +```console +kubectl get gatewayclass +``` + +The output should include the `azure-alb-external` GatewayClass. + +You can now deploy applications with Gateway API or Ingress resources and expose them through Application Gateway for Containers. + +## Disable the add-on + +To disable the ALB Controller add-on, apply an update that sets `applicationLoadBalancer.enabled` to `false`: + +```hcl +resource "azapi_update_resource" "disable_alb" { + type = "Microsoft.ContainerService/managedClusters@2025-09-02-preview" + resource_id = azurerm_kubernetes_cluster.aks.id + body = { + properties = { + ingressProfile = { + applicationLoadBalancer = { + enabled = false + } + } + } + } +} +``` + +Apply the change: + +```console +terraform apply +``` diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf new file mode 100644 index 000000000..1cd6f8976 --- /dev/null +++ b/quickstart/101-aks-alb-controller/main.tf @@ -0,0 +1,93 @@ +terraform { + required_version = ">= 1.6.0" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 4.0" + } + azapi = { + source = "Azure/azapi" + version = "~> 2.0" + } + random = { + source = "hashicorp/random" + version = "~> 3.6" + } + } +} + +provider "azurerm" { + features {} +} + +provider "azapi" {} + +resource "random_pet" "suffix" { + length = 2 +} + +locals { + resource_group_name = "rg-agfc-alb-${random_pet.suffix.id}" + aks_name = "aks-alb-${random_pet.suffix.id}" + location = "northeurope" +} + +resource "azurerm_resource_group" "rg" { + name = local.resource_group_name + location = local.location +} + +resource "azurerm_kubernetes_cluster" "aks" { + name = local.aks_name + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + dns_prefix = local.aks_name + oidc_issuer_enabled = true + workload_identity_enabled = true + + default_node_pool { + name = "systempool" + node_count = 2 + vm_size = "Standard_D2s_v5" + } + + identity { + type = "SystemAssigned" + } + + network_profile { + network_plugin = "azure" + network_policy = "azure" + load_balancer_sku = "standard" + } +} + +resource "azapi_update_resource" "enable_alb_controller_addon" { + type = "Microsoft.ContainerService/managedClusters@2025-09-02-preview" + resource_id = azurerm_kubernetes_cluster.aks.id + body = { + properties = { + ingressProfile = { + applicationLoadBalancer = { + enabled = true + } + gatewayAPI = { + installation = "Standard" + } + } + } + } +} + +output "resource_group_name" { + value = azurerm_resource_group.rg.name +} + +output "aks_cluster_name" { + value = azurerm_kubernetes_cluster.aks.name +} + +output "aks_cluster_id" { + value = azurerm_kubernetes_cluster.aks.id +} From 23a18b494469691de804efaada97acff7969f607 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 23 Aug 2026 20:27:40 +0000 Subject: [PATCH 02/12] Apply remaining changes Co-authored-by: Rebecca-Calixte <262454636+Rebecca-Calixte@users.noreply.github.com> --- quickstart/101-aks-alb-controller/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index 1cd6f8976..44049f5c6 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -49,7 +49,7 @@ resource "azurerm_kubernetes_cluster" "aks" { default_node_pool { name = "systempool" node_count = 2 - vm_size = "Standard_D2s_v5" + vm_size = "Standard_B2s_v2" } identity { From c25ad00b04c9d554f32c2d7b19f14add3e42ef2e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 26 Aug 2026 07:57:15 +0000 Subject: [PATCH 03/12] Reduce AKS ALB quickstart quota requirements for e2e Co-authored-by: vranade-microsoft <269690592+vranade-microsoft@users.noreply.github.com> --- quickstart/101-aks-alb-controller/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index 44049f5c6..0ee5e981a 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -48,8 +48,8 @@ resource "azurerm_kubernetes_cluster" "aks" { default_node_pool { name = "systempool" - node_count = 2 - vm_size = "Standard_B2s_v2" + node_count = 1 + vm_size = "Standard_DS2_v2" } identity { From d6c69f63c65f5b583e1d0501a22eccb7482d28f8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 26 Aug 2026 09:06:28 +0000 Subject: [PATCH 04/12] Fix VM size not allowed in subscription for AKS ALB quickstart e2e test Co-authored-by: vranade-microsoft <269690592+vranade-microsoft@users.noreply.github.com> --- quickstart/101-aks-alb-controller/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index 0ee5e981a..51ac729d8 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -49,7 +49,7 @@ resource "azurerm_kubernetes_cluster" "aks" { default_node_pool { name = "systempool" node_count = 1 - vm_size = "Standard_DS2_v2" + vm_size = "Standard_B2s_v2" } identity { From ab78e5541907ff87661e90c7f0167d2c164961a2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 26 Aug 2026 09:17:16 +0000 Subject: [PATCH 05/12] Use available low-priority AKS VM size Co-authored-by: vranade-microsoft <269690592+vranade-microsoft@users.noreply.github.com> --- quickstart/101-aks-alb-controller/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index 51ac729d8..6883d6e60 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -49,7 +49,7 @@ resource "azurerm_kubernetes_cluster" "aks" { default_node_pool { name = "systempool" node_count = 1 - vm_size = "Standard_B2s_v2" + vm_size = "Standard_B2ls_v2" } identity { From 8af37955098de24915423c7908a7a73d42621cf6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 26 Aug 2026 10:52:44 +0000 Subject: [PATCH 06/12] Use AKS VM family with available quota Co-authored-by: vranade-microsoft <269690592+vranade-microsoft@users.noreply.github.com> --- quickstart/101-aks-alb-controller/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index 6883d6e60..783bf9335 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -49,7 +49,7 @@ resource "azurerm_kubernetes_cluster" "aks" { default_node_pool { name = "systempool" node_count = 1 - vm_size = "Standard_B2ls_v2" + vm_size = "Standard_D2s_v3" } identity { From 60f6d3e616fcdf6e2d5fddd6ee5f606084c780af Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Aug 2026 07:16:04 +0000 Subject: [PATCH 07/12] Use allowed AKS VM size in ALB quickstart Co-authored-by: vranade-microsoft <269690592+vranade-microsoft@users.noreply.github.com> --- quickstart/101-aks-alb-controller/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index 783bf9335..6883d6e60 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -49,7 +49,7 @@ resource "azurerm_kubernetes_cluster" "aks" { default_node_pool { name = "systempool" node_count = 1 - vm_size = "Standard_D2s_v3" + vm_size = "Standard_B2ls_v2" } identity { From 2beace99dd4f695f69a94b6d6845e914511cee62 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 27 Aug 2026 07:41:31 +0000 Subject: [PATCH 08/12] Deploy ALB controller quickstart in eastus with available VM size Co-authored-by: vranade-microsoft <269690592+vranade-microsoft@users.noreply.github.com> --- quickstart/101-aks-alb-controller/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index 6883d6e60..e7ba3395a 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -30,7 +30,7 @@ resource "random_pet" "suffix" { locals { resource_group_name = "rg-agfc-alb-${random_pet.suffix.id}" aks_name = "aks-alb-${random_pet.suffix.id}" - location = "northeurope" + location = "eastus" } resource "azurerm_resource_group" "rg" { @@ -49,7 +49,7 @@ resource "azurerm_kubernetes_cluster" "aks" { default_node_pool { name = "systempool" node_count = 1 - vm_size = "Standard_B2ls_v2" + vm_size = "Standard_D2_v2" } identity { From d5f5e5ffa992b6a62c4d3cea496b333a88307e20 Mon Sep 17 00:00:00 2001 From: Rebecca Calixte Date: Thu, 27 Aug 2026 16:10:47 -0400 Subject: [PATCH 09/12] Change VM size in AKS node pool configuration --- quickstart/101-aks-alb-controller/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index e7ba3395a..4edfe3e20 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -49,7 +49,7 @@ resource "azurerm_kubernetes_cluster" "aks" { default_node_pool { name = "systempool" node_count = 1 - vm_size = "Standard_D2_v2" + vm_size = "Standard_D2s_v5" } identity { From 1a06d051ee039f1c18a9931893e47ca04dc7c9dc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 28 Aug 2026 14:40:54 +0000 Subject: [PATCH 10/12] Use AKS node size available in e2e subscription Co-authored-by: vranade-microsoft <269690592+vranade-microsoft@users.noreply.github.com> --- quickstart/101-aks-alb-controller/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index 4edfe3e20..caf9f3c25 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -49,7 +49,7 @@ resource "azurerm_kubernetes_cluster" "aks" { default_node_pool { name = "systempool" node_count = 1 - vm_size = "Standard_D2s_v5" + vm_size = "Standard_D2s_v7" } identity { From 143ae7c34b87d81e10a46a794eb107de15f10626 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 28 Aug 2026 15:11:24 +0000 Subject: [PATCH 11/12] Register AKS ALB Controller preview features in quickstart Co-authored-by: vranade-microsoft <269690592+vranade-microsoft@users.noreply.github.com> --- quickstart/101-aks-alb-controller/README.md | 12 +++++ quickstart/101-aks-alb-controller/main.tf | 54 +++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/quickstart/101-aks-alb-controller/README.md b/quickstart/101-aks-alb-controller/README.md index 165cd7c4e..a3c996078 100644 --- a/quickstart/101-aks-alb-controller/README.md +++ b/quickstart/101-aks-alb-controller/README.md @@ -12,6 +12,14 @@ The AzureRM provider does not currently expose the AKS `ingressProfile` configur - `kubectl` installed. - Permission to create AKS resources and assign the required roles. - The `Microsoft.ContainerService` and `Microsoft.ServiceNetworking` resource providers registered in the subscription. +- The `Microsoft.ContainerService/ApplicationLoadBalancerPreview` and `Microsoft.ContainerService/ManagedGatewayAPIPreview` preview features registered in the subscription. This sample registers them for you, but registration is subscription wide and can take several minutes to propagate. You can also register them up front with the Azure CLI: + + ```console + az feature register --namespace Microsoft.ContainerService --name ApplicationLoadBalancerPreview + az feature register --namespace Microsoft.ContainerService --name ManagedGatewayAPIPreview + az provider register --namespace Microsoft.ContainerService + ``` + - A supported Azure region for Application Gateway for Containers. - An AKS cluster using Azure CNI or Azure CNI Overlay. AKS Automatic clusters are not supported for this scenario. @@ -20,7 +28,9 @@ The AzureRM provider does not currently expose the AKS `ingressProfile` configur - [random_pet](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) - [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) - [azurerm_kubernetes_cluster](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster) +- [azapi_resource_action](https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/resource_action) - [azapi_update_resource](https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/update_resource) +- [time_sleep](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) ## Example @@ -54,6 +64,8 @@ ingressProfile = { } ``` +Because the preview features are registered as part of the same apply, the sample waits for the registration to propagate and retries the add-on enablement while the resource provider still reports `PreviewFeatureNotRegistered`. The first apply can therefore take longer than a regular AKS deployment. + ## Update an existing cluster For an existing AKS cluster, use data sources to reference the cluster and apply the same `ingressProfile` update: diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index caf9f3c25..f8acc14fa 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -14,6 +14,10 @@ terraform { source = "hashicorp/random" version = "~> 3.6" } + time = { + source = "hashicorp/time" + version = "~> 0.12" + } } } @@ -23,6 +27,8 @@ provider "azurerm" { provider "azapi" {} +data "azapi_client_config" "current" {} + resource "random_pet" "suffix" { length = 2 } @@ -31,6 +37,40 @@ locals { resource_group_name = "rg-agfc-alb-${random_pet.suffix.id}" aks_name = "aks-alb-${random_pet.suffix.id}" location = "eastus" + # The ALB Controller add-on and the managed Gateway API installation are in preview + # and require these subscription level feature registrations. + preview_features = [ + "ApplicationLoadBalancerPreview", + "ManagedGatewayAPIPreview", + ] +} + +resource "azapi_resource_action" "register_preview_features" { + for_each = toset(local.preview_features) + + type = "Microsoft.Features/featureProviders/subscriptionFeatureRegistrations@2021-07-01" + resource_id = "${data.azapi_client_config.current.subscription_resource_id}/providers/Microsoft.Features/featureProviders/Microsoft.ContainerService/subscriptionFeatureRegistrations/${each.value}" + method = "PUT" + body = { + properties = {} + } +} + +# Feature registration is asynchronous, wait before refreshing the resource provider. +resource "time_sleep" "wait_for_feature_registration" { + create_duration = "10m" + + depends_on = [azapi_resource_action.register_preview_features] +} + +# Re-registering the resource provider propagates the registered preview features. +resource "azapi_resource_action" "register_container_service" { + type = "Microsoft.Resources/providers@2021-04-01" + resource_id = "${data.azapi_client_config.current.subscription_resource_id}/providers/Microsoft.ContainerService" + action = "register" + method = "POST" + + depends_on = [time_sleep.wait_for_feature_registration] } resource "azurerm_resource_group" "rg" { @@ -78,6 +118,20 @@ resource "azapi_update_resource" "enable_alb_controller_addon" { } } } + + # Keep retrying while the preview feature registrations propagate to the resource provider. + retry = { + error_message_regex = ["PreviewFeatureNotRegistered"] + interval_seconds = 60 + max_interval_seconds = 300 + } + + timeouts { + create = "90m" + update = "90m" + } + + depends_on = [azapi_resource_action.register_container_service] } output "resource_group_name" { From bdefa49527173fdc89cdebcd69a50f039da61ef5 Mon Sep 17 00:00:00 2001 From: Rebecca Calixte Date: Mon, 31 Aug 2026 08:41:42 -0400 Subject: [PATCH 12/12] Add upgrade settings to default node pool Added upgrade settings to the default node pool configuration. --- quickstart/101-aks-alb-controller/main.tf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/quickstart/101-aks-alb-controller/main.tf b/quickstart/101-aks-alb-controller/main.tf index f8acc14fa..0c91493f2 100644 --- a/quickstart/101-aks-alb-controller/main.tf +++ b/quickstart/101-aks-alb-controller/main.tf @@ -90,6 +90,12 @@ resource "azurerm_kubernetes_cluster" "aks" { name = "systempool" node_count = 1 vm_size = "Standard_D2s_v7" + +upgrade_settings { + drain_timeout_in_minutes = 0 + max_surge = "10%" + node_soak_duration_in_minutes = 0 + } } identity {