This architecture provides secure ingress through Azure Application Gateway (WAF_v2) to Azure API Management (APIM) deployed in a Virtual Network using Internal mode (private IP only). No private endpoints are used; traffic stays on private networking after the gateway, and APIM cannot be accessed aside from traversing Application Gateway.
Diagram created with the Azure Draw.io MCP Server.
- Expose APIs publicly via Application Gateway while keeping APIM private (VNet Internal)
- Maintain private networking end-to-end without private endpoints
- Enable optional backends with Azure Container Apps (ACA)
- Provide observability via Log Analytics and Application Insights
- Significant cost savings for learning, demos, and dev/test:
- Developer is a fraction of Premium costs (often >90% cheaper)
- No SLA and single-instance only, which is acceptable for the purpose of this repo
- Trade-offs:
- Longer deployment times compared to v2/Premium SKUs (APIM creation can be slow)
We choose the Developer SKU here to dramatically lower costs for experimentation. If you need SLAs, scaling, or production-grade features, use Premium or Premiumv2 because those SKUs also support VNet injection.
Adjust the user-defined parameters in this lab's Jupyter Notebook's Initialize notebook variables section.
Key parameters:
apimSku: Defaults toDeveloperuseACA: Enable to provision a private ACA environment and sample appsuse_strict_nsg: Optional system configuration flag, defaults toFalse
We provide NSG deployment as an option for teams that want to experiment with subnet-level controls, but we intentionally keep it disabled by default. This repository aims to stay practical and focused on APIM learning scenarios rather than bundling in too much Azure Landing Zone-style network governance complexity.
NSG behavior:
nsg-default: Generic fallback NSG for subnets that do not have a service-specific NSG. It stays intentionally generic.use_strict_nsg = False: Service subnets get permissive service-aware NSGs:nsg-appgw,nsg-apim, andnsg-aca. These preserve Azure platform requirements and avoid unnecessary ingress restrictions.use_strict_nsg = True: Service subnets get strict NSGs:nsg-appgw-strict,nsg-apim-strict, andnsg-aca-strict. These keep required platform rules but restrict ingress so traffic follows App Gateway -> APIM -> ACA.
- Execute this lab's Jupyter Notebook step-by-step or via Run All.
👟 Expected Run All runtime: longer than v2 SKUs for APIM creation. We will measure and update this value after testing.
- TODO: Measure actual runtime on Developer SKU and update this section accordingly.
Because we use a self-signed certificate for Application Gateway TLS termination (for convenience in this sample), testing can be done with curl by ignoring certificate warnings and sending the Host header:
curl -v -k -H "Host: api.apim-samples.contoso.com" https://<APPGW_PUBLIC_IP>/status-0123456789abcdef
A 200 status from the health endpoint indicates success through App Gateway to APIM.
- Self-signed certificates are for demos only. Use managed or trusted certs for production.
- This sample uses RBAC-enabled Key Vault with minimal role assignments for App Gateway certificate retrieval.
- Azure limitation: APIM must be created with public access enabled initially. You can disable public access in a subsequent update if desired.
- Review and harden NSGs/WAF policy as needed for your environment.