aboutBlog

Learn DevOps Step-by-Step Tutorials and fixing related issues.

Welcome to Py-Bucket, your go-to blog for DevOps tutorials and production issues fixes guide.

  • ✔ Beginner-friendly DevOps guides
  • ✔ Real-world production issues and fixes

Application Gateway for Containers on Existing AKS Using Terraform: A Practical Deployment Guide

Application Gateway for Containers on Existing AKS Using Terraform: A Practical Deployment Guide



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/trafficControllers is 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 modelResource lifecycleBest suited for
BYOAzure resources are created and managed separately; Kubernetes references them.Teams wanting explicit infrastructure ownership through Terraform.
Managed by ALB ControllerController 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.

What "BYO" means here

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.

LayerToolResponsibility
Azure resourcesTerraform with the azapi providerResource group, delegated subnet, AGC, frontend, subnet association, managed identity, role assignments, federated credential
ControllerHelm (run from the CLI, not from Terraform)Installs the ALB Controller in namespace azure-alb-system
Kubernetes objectskubectlTest 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 versus managed

BYO (this guide)Managed
Who creates the AGCTerraformThe ALB Controller, from the ApplicationLoadBalancer resource
Gateway annotationsalb-id plus the frontend addressalb-namespace plus alb-name
ApplicationLoadBalancer resourceNot createdRequired
Config Manager role scope for the UAMIAGC resource groupAKS node resource group
SubnetThe Terraform subnet and associationA separate delegated subnet, association made by the controller


What Are the Prerequisites for Existing AKS?

Before deployment, confirm your AKS cluster, Azure subscription, and network meet the requirements for your chosen deployment model. 

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 tsv

Expected 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 yaml

make 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

- Check managed resource group
- Check running pods in namespaces.

Step 2: Create or delegate the gateway subnet

# AG4C association subnet — delegated to Microsoft.ServiceNetworking/trafficControllers
resource "azapi_resource" "subnet_agc" {
name = "subnet-agc"
parent_id = data.azurerm_virtual_network.vnet.id
type = "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 = 30
max_interval_seconds = 120
}
}
#------------------------------------------------------------------------------
# agc module
#------------------------------------------------------------------------------
module "agc" {
source = "./terraform-azurerm-avm-res-servicenetworking-trafficcontroller-main"
location = data.azurerm_kubernetes_cluster.aks.location
name = "agc-for-aks"
parent_id = data.azurerm_resource_group.rg.id
associations = {
main = {
name = "association-main"
subnet_resource_id = azapi_resource.subnet_agc.id
}
}
enable_telemetry = var.enable_telemetry
frontends = {
web = {
name = "frontend-web"
}
}
}
Confirm subnet size and service requirements using your VNet address plan.

Step 3: Configure ALB Controller

ALB Controller observes Kubernetes configuration and communicates with Azure. Supported deployment paths include the Helm-based installation.
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

UAMI used by the ALB Controller Access

RoleScopeWhy it is needed
AppGw for Containers Configuration ManagerAGC resource groupRead and write AGC configuration: listeners, routes, backends
Network ContributorAGC subnetPermission to join the delegated subnet, needed for the association
ReaderAKS node resource group (MC_*)Discover the cluster networking so backends can be programmed
refer the code from matrubhashaai repo, for how can you write terraform code for the access.

refer main.tf here for the role assignment code.
az role assignment list \
  --scope <subnet-resource-id> \
  --include-inherited \
  --output table

Expected: the intended controller principal has the required subnet permission at the correct scope.

Step 5: Apply Terraform carefully

A maintainable Terraform project may separate provider configuration, data sources, networking, identity, role assignments, gateway resources, variables, and outputs. Keep existing AKS resources as data sources unless you intentionally manage their lifecycle in the same state.

terraform init
terraform fmt -check
terraform validate
terraform plan -out=tfplan 
terraform apply tfplan
Review the plan for accidental AKS replacement, subnet recreation, identity replacement, or role assignments at an unexpected scope. Terraform completion confirms infrastructure operations—not end-to-end routing.

Step 6: Configure Gateway API resources

Gateway API separates infrastructure configuration from application routing. A Gateway defines listeners; an HTTPRoute defines how matching requests reach Kubernetes Services. 
refer the code from matrubhashaai repo, for how can you write kubernetes manifests for gateway.

Apply the kubernetes manifests files

Gateway and httproute included here in this file

kubectl apply -f gateway.yml

Step 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

Issue 1: Gateway says ApplicationLoadBalancer resource "alb-infra/alb-test" ... was not found

  • Cause: the Gateway was first created with the managed annotations (alb-namespace, alb-name).
  • Fix: remove them. Use only alb-id plus the addresses frontend name. Check that no stray ApplicationLoadBalancer exists with kubectl get applicationloadbalancer -A, and delete any left over from testing.

Issue 2: Gateway status looks stale (observedGeneration is lower than metadata.generation)

  • 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.

Issue 3: Gateway shows "Waiting for controller"

  • Meaning: no controller has claimed the Gateway yet.
  • Checks, in order:
    1. Are the two pods in azure-alb-system running and 1/1?
    2. Does kubectl get gatewayclass list azure-alb-external as accepted?
    3. Does helm list -n azure-alb-system show the release as deployed?
    4. Does the Gateway's gatewayClassName match the class exactly?
  • Common mistake: pasting kubectl delete gateway ... and kubectl apply ... on one line. Kubectl then treats extra words as object names. Run them as separate commands.

Issue 4: Controller logs show errors

Log messageCauseFix
AuthorizationFailed or 403A UAMI role is missing, or has not propagatedConfirm all three role assignments and scopes, wait, restart the controller
AADSTS70021 or no matching federated identityFederated credential subject or issuer is wrongSubject must be exactly system:serviceaccount:azure-alb-system:alb-controller-sa, issuer must be the AKS OIDC URL
Token or workload identity errorsWorkload identity is not enabled on AKSEnable OIDC issuer and workload identity on the cluster
ImagePullBackOff on controller podsNodes cannot reach mcr.microsoft.comCheck outbound access, firewall, and routes
Wrong identity usedObject (principal) ID used instead of client ID in HelmUse 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.


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.


You may like reading below links

Kubernetes Architecture & Components: A Beginner’s Guide

Kubernetes: The Ultimate Guide to Container Orchestration & Scalability

What Is Azure Application Gateway? How It Works, Features & Use Cases (2026)


Featured posts

🔥 Featured Tutorials

Devops

DevOps Tutorials

Author Details

Hi, I'm Prashant — a full-time software engineer with a passion for automation, DevOps, and sharing what I learn. I started Py-Bucket to document my journey through tools like Docker, Kubernetes, Azure DevOps, and PowerShell scripting — and to help others navigate the same path. When I’m not coding or writing, I’m experimenting with side projects, exploring productivity hacks, or learning how to build passive income streams online. This blog is my sandbox — and you're welcome to explore it with me. Get in touch or follow me for future updates!