- Terraform IaC (modular) to provision Azure RG, VNet, AKS, ACR, Log Analytics, identities/role assignments.
- A minimal REST app (Python + Flask) returning the exact payload required.
- Kubernetes manifests (Deployment, ClusterIP Service, Namespace, Istio
Gateway+VirtualService) for AKS. - Azure DevOps YAML pipeline for build/test/push/deploy + smoke test.
- README with deploy & cleanup steps.
Note: An Istio Gateway + VirtualService and the app
Serviceas ClusterIP; as this will expose the app via the Istio ingress gateway (LoadBalancer) while keeping the workload service internal, even if the platform is public-facing.
AKS managed Istio add‑on
# Enable Istio add-on; then enable external ingress gateway (public IP)
az aks mesh enable --resource-group rg --name aksname
az aks mesh enable-ingress-gateway --resource-group rg --name aksname --ingress-gateway-type external
kubectl get svc aks-istio-ingressgateway-external -n aks-istio-ingress- Azure RG + VNet/Subnet
- AKS (node pool, managed identity), Log Analytics
- ACR (image store)
- Istio (control plane + ingress gateway)
- Azure DevOps (YAML pipeline)
- Python Flask App - The simple application providing the required REST endpoint.
-
Developer → commit → Azure DevOps pipeline (ci build + deploy stages) → deploy manifests (and apply istio manifests) → AKS
-
DevOps → commit tf Code → Azure DevOps pipeline (tf init & plan stage) → TF apply stage → Azure Platform
-
Client → Istio Ingress Gateway (LoadBalancer) →
VirtualServiceroutes/api→ internalClusterIPService→Deploymentpods -
Application Flow
- Client Request: A user sends an HTTP GET request to http://<ISTIO_GATEWAY_IP>/api/status.
- Azure Networking: The request hits the public IP of the Istio Ingress Gateway service (LoadBalancer type).
- Istio Gateway/VirtualService: Istio receives the request and, based on defined rules, routes the traffic internally to the application's ClusterIP Service.
- K8s Service: The ClusterIP Service load-balances the request to one of the healthy application Pods.
- Application Pod: The Python Flask application processes the request and returns the JSON payload {"message": "Automate all the things!", "timestamp": ...} with an HTTP 200 status.
- Response: The response traverses back through the service mesh and gateway to the client.
You can find the endpoint in the YAML last task
task: Smoke test via Istio gatewayto get ingress url.
- task: Bash@3
displayName: Smoke test via Istio gateway
...
echo "INGRESS IP: $IP"
echo "Smoke test: GET http://$IP/api/message"OR...
# Get external IP of Istio gateway
kubectl get svc aks-istio-ingressgateway-external -n aks-istio-ingress
curl http://<IP>/api/message
# Expected:
# { "message": "Automate all the things!", "timestamp": 1529729125 }