Browser or API client resolves the public hostname (Azure DNS / external DNS) to the public IP of the Azure Load Balancer.
Public frontend receives HTTPS traffic and forwards it to Traefik pods (node ports / internal endpoints) inside the AKS node pool.
Traefik matches the Ingress rule, terminates TLS using a cert-manager managed certificate (Let's Encrypt), and routes to the Flask Service.
ClusterIP Service load-balances to healthy Flask/Gunicorn pods. Request hits the app (e.g. /, /api/status).
If the handler needs data, the app opens a connection to the in-cluster postgres service (StatefulSet). No traffic leaves the cluster for DB access.
Response flows back: Pod โ Service โ Traefik (re-encrypts or already TLS at edge) โ Load Balancer โ Client.
Pipeline jobs run on an agent inside the private VNet so it can reach the private AKS API server and ACR as needed.
Agent builds the Docker image and pushes it to Azure Container Registry.
Agent runs Helm against the private cluster API, rolling out the new Deployment / StatefulSet revisions. No public control-plane exposure.