Already running workloads on Azure Kubernetes Service (AKS) and want to introduce Application Gateway for Containers without rebuilding your cluster? The challenge is connecting Azure networking, managed identity, ALB Controller, and Kubernetes Gateway API without disrupting existing workloads. This guide explains the deployment approach, validation commands, and diagnostic decision trees.
Key Takeaways
- Application Gateway for Containers is a managed Layer 7 ingress service for AKS workloads.
- You can integrate it with an existing AKS cluster; creating a new cluster is not always required.
- ALB Controller translates Kubernetes routing resources into Azure gateway configuration.
- BYO and controller-managed deployment models have different resource lifecycle responsibilities.
- A dedicated subnet delegated to
Microsoft.ServiceNetworking/trafficControllersis a key networking requirement. - Identity permissions, Workload Identity, and outbound connectivity are common deployment checkpoints.
- A successful Terraform apply does not prove that traffic is flowing; validate Kubernetes status and backend connectivity.
What Is Application Gateway for Containers on Existing AKS?
Application Gateway for Containers on existing AKS is a managed Azure Layer 7 ingress solution that routes HTTP and HTTPS traffic to workloads in an already-deployed Kubernetes cluster. ALB Controller interprets Kubernetes resources and configures the Azure-managed data plane.
It is distinct from traditional Azure Application Gateway and Application Gateway Ingress Controller (AGIC). Its architecture supports Kubernetes-native configuration, including Gateway API and Ingress.
Why Is Application Gateway for Containers Important for Existing AKS?
It helps teams modernize ingress while keeping their current cluster, workloads, and deployment pipelines in place. Common reasons include Kubernetes-native routing, centralized ingress, Layer 7 controls, staged migration, and a managed data plane.
Use it when you need Kubernetes-oriented HTTP/HTTPS ingress or Gateway API routing. Consider alternatives when you only need Layer 4 load balancing, your current ingress already meets requirements, or your application needs a feature not supported by the service.
What Are the Deployment Models?
Application Gateway for Containers supports BYO (Bring Your Own) and ALB Controller-managed deployment. The key difference is who owns the lifecycle of Azure gateway resources.
| Deployment model | Resource lifecycle | Best suited for |
|---|---|---|
| BYO | Azure resources are created and managed separately; Kubernetes references them. | Teams wanting explicit infrastructure ownership through Terraform. |
| Managed by ALB Controller | Controller creates and manages gateway resources based on Kubernetes custom resources. | Teams preferring controller-managed lifecycle. |
Practical rule: Choose the model before writing Terraform. Do not mix BYO lifecycle assumptions with controller-managed resource assumptions.
We will see the BYO model in this blog.
In BYO (Bring Your Own), you create the Application Gateway for Containers (AGC) yourself, and the ALB Controller in the cluster only connects to it.
| Layer | Tool | Responsibility |
|---|---|---|
| Azure resources | Terraform with the azapi provider | Resource group, delegated subnet, AGC, frontend, subnet association, managed identity, role assignments, federated credential |
| Controller | Helm (run from the CLI, not from Terraform) | Installs the ALB Controller in namespace azure-alb-system |
| Kubernetes objects | kubectl | Test application, your own Gateway, your own HTTPRoute |
Because the AGC already exists, you do not create the ApplicationLoadBalancer custom resource. That resource belongs to the managed model.
| BYO (this guide) | Managed | |
|---|---|---|
| Who creates the AGC | Terraform | The ALB Controller, from the ApplicationLoadBalancer resource |
| Gateway annotations | alb-id plus the frontend address | alb-namespace plus alb-name |
ApplicationLoadBalancer resource | Not created | Required |
| Config Manager role scope for the UAMI | AGC resource group | AKS node resource group |
| Subnet | The Terraform subnet and association | A separate delegated subnet, association made by the controller |
What Are the Prerequisites for Existing AKS?
Confirm required resource providers
az provider register --namespace Microsoft.ContainerService
az provider register --namespace Microsoft.Network
az provider register --namespace Microsoft.ServiceNetworking
az provider show \
--namespace Microsoft.ServiceNetworking \
--query registrationState \
--output tsvExpected output: Registered. If the provider is still registering, wait and check again before creating dependent resources.
Plan a dedicated subnet
Application Gateway for Containers uses a subnet with the delegation Microsoft.ServiceNetworking/trafficControllers. Confirm its address range, delegation, and network design before applying changes.
az network vnet subnet show \
--resource-group <vnet-resource-group> \
--vnet-name <vnet-name> \
--name <alb-subnet-name> \
--output yamlmake sure your delegated subnet is /24 or larger
How Do You Deploy Application Gateway for Containers on Existing AKS Using Terraform?
Step 1: Inspect existing Azure resources
Step 2: Create or delegate the gateway subnet
# AG4C association subnet — delegated to Microsoft.ServiceNetworking/trafficControllersresource "azapi_resource" "subnet_agc" {name = "subnet-agc"parent_id = data.azurerm_virtual_network.vnet.idtype = "Microsoft.Network/virtualNetworks/subnets@2024-05-01"body = {properties = {addressPrefix = "10.0.2.0/24"delegations = [{name = "agc-delegation"properties = {serviceName = "Microsoft.ServiceNetworking/trafficControllers"}}]}}# The Application Gateway for Containers association keeps the subnet briefly# "in use" after it is deleted; retry the subnet deletion until it is released.retry = {error_message_regex = ["InUseSubnetCannotBeDeleted"]interval_seconds = 30max_interval_seconds = 120}}#------------------------------------------------------------------------------# agc module#------------------------------------------------------------------------------module "agc" {source = "./terraform-azurerm-avm-res-servicenetworking-trafficcontroller-main"location = data.azurerm_kubernetes_cluster.aks.locationname = "agc-for-aks"parent_id = data.azurerm_resource_group.rg.idassociations = {main = {name = "association-main"subnet_resource_id = azapi_resource.subnet_agc.id}}enable_telemetry = var.enable_telemetryfrontends = {web = {name = "frontend-web"}}}
Step 3: Configure ALB Controller
az aks get-credentials \ --resource-group <aks-resource-group> \
--name <aks-cluster-name> \
--overwrite-existing
helm install alb-controller oci://mcr.microsoft.com/application-lb/charts/alb-controller \
--namespace azure-alb-system \
--create-namespace \
--version 1.12.4 \
--set albController.namespace=azure-alb-system \
--set albController.podIdentity.clientID=********************
kubectl get pods -A | grep -i alb
kubectl get crd | grep -i alb
Expected: controller pods are healthy and required CRDs are installed.
Step 4: Assign Azure permissions at the correct scope
| Role | Scope | Why it is needed |
|---|---|---|
| AppGw for Containers Configuration Manager | AGC resource group | Read and write AGC configuration: listeners, routes, backends |
| Network Contributor | AGC subnet | Permission to join the delegated subnet, needed for the association |
| Reader | AKS node resource group (MC_*) | Discover the cluster networking so backends can be programmed |
az role assignment list \
--scope <subnet-resource-id> \
--include-inherited \
--output tableExpected: the intended controller principal has the required subnet permission at the correct scope.
Step 5: Apply Terraform carefully
terraform init
terraform fmt -check
terraform validate
terraform plan -out=tfplan
terraform apply tfplanStep 6: Configure Gateway API resources
kubectl apply -f gateway.ymlStep 7: Verify Gateway and route status
kubectl get gatewayclass
kubectl get gateway -A
kubectl get httproute -A
kubectl describe gateway app-gateway -n <namespace>
kubectl describe httproute app-route -n <namespace>
kubectl get gateway app-gateway -n <namespace> \
-o jsonpath='{range .status.conditions[*]}{.type}={.status}{" | "}{.reason}{"\n"}{end}'Look for conditions such as Accepted and Programmed where applicable. A resource can exist in Kubernetes while remaining unaccepted or not programmed.
How Do You Troubleshoot Application Gateway for Containers on Existing AKS?
Troubleshoot from the controller outward to the frontend and then to the backend. Identify the failing layer before changing infrastructure.
What Are the Common Mistakes?
- Rebuilding AKS unnecessarily: Some quickstarts create a new cluster for demonstration. Adapt their infrastructure steps for an existing cluster.
- Mixing lifecycle models: Decide whether Terraform or ALB Controller owns gateway resource lifecycle.
- Using the wrong subnet: Confirm delegation and network design before changing a subnet.
- Assigning permissions to the wrong identity: Terraform and ALB Controller may use different principals.
- Ignoring Gateway API status: Created objects may still be rejected or not programmed.
- Changing multiple layers at once: Make one evidence-based change and validate it before proceeding.
Troubleshooting
- Cause: the Gateway was first created with the managed annotations (
alb-namespace,alb-name). - Fix: remove them. Use only
alb-idplus theaddressesfrontend name. Check that no strayApplicationLoadBalancerexists withkubectl get applicationloadbalancer -A, and delete any left over from testing.
- Meaning: you corrected the Gateway (generation moved on), but the status still shows the controller's result from the old version. The old error message no longer applies.
- Cause: the controller is not reconciling, because it is down, crashing, or failing with authorization errors.
- Fix: check the controller pods and logs, restart the controller deployment, and if it stays stale, delete and re-apply the Gateway so it starts fresh at generation 1.
- Meaning: no controller has claimed the Gateway yet.
- Checks, in order:
- Are the two pods in
azure-alb-systemrunning and1/1? - Does
kubectl get gatewayclasslistazure-alb-externalas accepted? - Does
helm list -n azure-alb-systemshow the release as deployed? - Does the Gateway's
gatewayClassNamematch the class exactly?
- Are the two pods in
- Common mistake: pasting
kubectl delete gateway ...andkubectl apply ...on one line. Kubectl then treats extra words as object names. Run them as separate commands.
| Log message | Cause | Fix |
|---|---|---|
AuthorizationFailed or 403 | A UAMI role is missing, or has not propagated | Confirm all three role assignments and scopes, wait, restart the controller |
AADSTS70021 or no matching federated identity | Federated credential subject or issuer is wrong | Subject must be exactly system:serviceaccount:azure-alb-system:alb-controller-sa, issuer must be the AKS OIDC URL |
| Token or workload identity errors | Workload identity is not enabled on AKS | Enable OIDC issuer and workload identity on the cluster |
ImagePullBackOff on controller pods | Nodes cannot reach mcr.microsoft.com | Check outbound access, firewall, and routes |
| Wrong identity used | Object (principal) ID used instead of client ID in Helm | Use the client ID |
Conclusion
Application Gateway for Containers can help you modernize ingress on an existing AKS cluster without rebuilding your Kubernetes environment. By combining Terraform, ALB Controller, and Gateway API, you can build a scalable and Kubernetes-native traffic management solution.
Validate the subnet, identity permissions, Gateway status, and backend connectivity carefully to ensure a successful deployment.
Validate the subnet, identity permissions, Gateway status, and backend connectivity carefully to ensure a successful deployment.
Frequently Asked Questions (FAQs)
1. Can I deploy Application Gateway for Containers on an existing AKS cluster?
Yes. Application Gateway for Containers can be integrated with an existing AKS cluster, provided the cluster and Azure networking meet the service requirements. You do not necessarily need to create a new AKS cluster.
2. What is Application Gateway for Containers in AKS?
Application Gateway for Containers is a managed Layer 7 ingress solution for Kubernetes workloads. It handles HTTP and HTTPS traffic and supports Kubernetes-native configuration through Gateway API and Ingress resources.
3. What is the difference between BYO and ALB Controller-managed deployment?
In the BYO model, you create and manage the Application Gateway for Containers Azure resources separately, for example, through Terraform. The ALB Controller connects the gateway to Kubernetes routing resources.
In the controller-managed model, the ALB Controller manages the gateway resource lifecycle using the ApplicationLoadBalancer custom resource.
4. Do I need to create an ApplicationLoadBalancer resource when using the BYO model?
No. In the BYO model, the Application Gateway for Containers resource is created separately, and the Gateway references it. The ApplicationLoadBalancer custom resource is used for the controller-managed deployment model.
5. Why does Application Gateway for Containers require a dedicated delegated subnet?
The gateway uses a subnet delegated to Microsoft.ServiceNetworking/trafficControllers. The subnet must be planned according to the service requirements and your Azure virtual network design. Confirm the required subnet size and configuration before deployment.
6. What is the role of the ALB Controller in AKS?
The ALB Controller runs in the AKS cluster and observes Kubernetes routing resources. It communicates with Azure and translates Gateway API or Ingress configuration into the corresponding Application Gateway for Containers configuration.
7. Why is my Gateway showing "Waiting for controller"?
This status can indicate that the Gateway has not yet been claimed or reconciled by the controller. Check that the ALB Controller pods are healthy, the GatewayClass is accepted, the Helm release is deployed, and the Gateway references the correct gatewayClassName.
8. Does a successful Terraform apply mean Application Gateway for Containers is working?
No. Terraform completion confirms that the infrastructure operations were applied, but it does not prove that end-to-end traffic is flowing. Verify the ALB Controller, Gateway and HTTPRoute status, backend Service connectivity, and application response.
9. How can I troubleshoot Application Gateway for Containers on AKS?
Start by checking the ALB Controller pods and logs. Then inspect the GatewayClass, Gateway, and HTTPRoute status conditions. Verify Azure role assignments, workload identity configuration, subnet delegation, and backend connectivity. Troubleshoot one layer at a time rather than changing multiple components simultaneously.
10. Can Application Gateway for Containers replace the traditional Azure Application Gateway or AGIC?
Application Gateway for Containers is a distinct Azure ingress service with Kubernetes-oriented configuration. Whether it can replace an existing Application Gateway or AGIC deployment depends on your current architecture, required features, and migration needs. Review the service capabilities before planning a migration.