Networking Operations¶
This guide covers networking operations for Container Apps: ingress updates, VNet-related checks, and service discovery between apps.
Prerequisites¶
- Container Apps environment deployed with required network model
- Ingress requirements documented (internal vs external)
Ingress Configuration Operations¶
Enable external ingress with explicit target port:
az containerapp ingress enable \
--name "$APP_NAME" \
--resource-group "$RG" \
--type external \
--target-port 8000
Ingress Flow¶
flowchart TD
subgraph ControlPlane [Azure Control Plane]
CLI[Azure CLI: az containerapp ingress enable]
ARM[Azure Resource Manager]
end
subgraph DataPlane [Container Apps Data Plane]
ENV[Envoy Managed Ingress]
POD[App Revision]
end
CLI -- Update Request --> ARM
ARM -- Configure --> ENV
ENV -- Route Traffic --> POD Switch to internal ingress for private-only access:
az containerapp ingress enable \
--name "$APP_NAME" \
--resource-group "$RG" \
--type internal \
--target-port 8000
Verify Ingress Configuration¶
Control-plane check — confirm ingress type and target port:
az containerapp show \
--name "$APP_NAME" \
--resource-group "$RG" \
--query "properties.configuration.ingress" \
--output json
az containerapp ingress show \
--name "$APP_NAME" \
--resource-group "$RG" \
--output json
Expected output (PII masked):
{
"allowInsecure": false,
"external": true,
"fqdn": "ca-myapp.<hash>.<region>.azurecontainerapps.io",
"targetPort": 8000,
"transport": "Auto",
"traffic": [
{
"latestRevision": true,
"weight": 100
}
]
}
Data-plane check — confirm the app responds on the FQDN:
# For external ingress
FQDN=$(az containerapp show \
--name "$APP_NAME" \
--resource-group "$RG" \
--query "properties.configuration.ingress.fqdn" \
--output tsv)
curl --silent --output /dev/null --write-out "%{http_code}" "https://$FQDN/health"
Expected result: 200
Example health payload:
Internal ingress
Internal ingress FQDNs resolve only from within the same VNet. Run the data-plane check from a VM or pod inside the environment's VNet.
VNet and Environment Checks¶
VNet Setup Flow¶
flowchart LR
subgraph Infrastructure [Azure Infrastructure]
VNET[Virtual Network / Subnet]
DEL[Subnet Delegation]
CAE[Managed Environment]
end
VNET -- 1. Create Subnet (/23) --> DEL
DEL -- 2. Delegate to Microsoft.App/environments --> CAE
CAE -- 3. Assign infrastructureSubnetId --> VNET Inspect managed environment network profile:
Validate subnet details (Azure CLI network command):
az network vnet subnet show \
--resource-group "$RG" \
--vnet-name "vnet-aca-prod" \
--name "snet-containerapps" \
--output table
Verify VNet Integration¶
Control-plane check — confirm the environment is attached to a VNet:
az containerapp env show \
--name "$ENVIRONMENT_NAME" \
--resource-group "$RG" \
--query "{vnetConfig: properties.vnetConfiguration, staticIp: properties.staticIp}" \
--output json
Expected output (PII masked):
Data-plane check — confirm subnet delegation is correct:
az network vnet subnet show \
--resource-group "$RG" \
--vnet-name "vnet-aca-prod" \
--name "snet-containerapps" \
--query "delegations[].serviceName" \
--output tsv
Expected result: Microsoft.App/environments
Service Discovery Operations¶
For app-to-app calls in the same environment, use internal FQDN from ingress settings.
az containerapp show \
--name "$APP_NAME" \
--resource-group "$RG" \
--query "properties.configuration.ingress.fqdn" \
--output tsv
Verify Service Discovery¶
Control-plane check — retrieve the internal FQDN of the target app:
az containerapp show \
--name "$APP_NAME" \
--resource-group "$RG" \
--query "properties.configuration.ingress.{fqdn: fqdn, external: external}" \
--output json
Expected output (internal app):
Data-plane check — confirm DNS resolution from another app in the same environment using an exec session:
# Run from inside the calling container (exec into container)
nslookup ca-myapp.internal.<region>.azurecontainerapps.io
Expected result: The FQDN resolves to the environment's internal IP (e.g., 10.0.x.x).
Cross-environment calls
Internal FQDNs are scoped to the environment. Apps in different environments cannot reach each other via these FQDNs — use VNet peering or public endpoints for cross-environment communication.
Network Debugging Checklist¶
When connectivity issues arise with privately networked resources, follow this systematic approach. Each step targets a specific OSI layer to isolate the problem.
Diagnostic Flow¶
flowchart TD
Start["Connectivity Issue"] --> DNS["1. nslookup hostname"]
DNS -->|"Resolves to public IP\nor NXDOMAIN"| DNSFix["❌ Check Private DNS Zone\nand VNet link"]
DNS -->|"Resolves to private IP\n(10.x.x.x)"| Ping["2. ping private-ip"]
Ping -->|"Timeout / unreachable"| PingFix["❌ Check NSG rules,\nroute tables, VNet peering"]
Ping -->|"Reachable"| Port["3. nc private-ip:port"]
Port -->|"Connection refused\nor timeout"| PortFix["❌ Check target service\nfirewall, port config"]
Port -->|"Port open"| App["4. curl https://endpoint"]
App -->|"HTTP error\n(401/403/5xx)"| AppFix["❌ Check auth config,\ncertificates, app health"]
App -->|"200 OK"| Done["✅ Connection working"] Step 1: DNS Resolution (Layer 7 — Application/DNS)¶
Run diagnostics from inside a running Container App revision.
az containerapp exec \
--resource-group "$RG" \
--name "$APP_NAME" \
--command "/bin/sh"
# In the container shell
nslookup your-private-resource.database.windows.net
Expected: private hostname resolves to a private IP.
If DNS fails (NXDOMAIN) or returns a public IP, fix private DNS configuration and VNet linkage.
Step 2: Network Reachability (Layer 3 — Network)¶
Check basic IP-level reachability from the same container network context.
If ping is unavailable in your image, install tooling in a debug session (for example, apt-get update && apt-get install -y iputils-ping dnsutils netcat-openbsd curl).
Step 3: Port Connectivity (Layer 4 — Transport)¶
Because tcpping is not typically available in Container Apps, use nc or curl --connect-timeout.
# TCP port probe
nc -zv 10.0.2.4 443
# HTTPS connect timeout probe
curl --connect-timeout 5 --verbose https://your-private-api.contoso.local/health
If port probe fails, investigate service-side firewall rules, listener ports, and NSG/UDR controls.
Step 4: Application Response (Layer 7 — Application)¶
Validate application response after network and transport checks succeed.
Expected: HTTP/1.1 200 OK (or service-specific success response).
Service-Specific Commands (Container Apps)¶
Inside the container, use: - nslookup <hostname> - ping -c 4 <private-ip> - nc -zv <host> <port> - curl --connect-timeout 5 https://<endpoint>
Common Failures by Layer¶
| Symptom | OSI Layer | Likely Cause | Fix |
|---|---|---|---|
NXDOMAIN or public IP | L7 (DNS) | Private DNS Zone missing or not linked | Create/link Private DNS Zone to VNet |
| Private IP but unreachable | L3 (Network) | NSG blocking, missing route, peering issue | Check NSG rules and route tables |
| IP reachable, port closed | L4 (Transport) | Service firewall, wrong port, service stopped | Check target service network rules |
| Port open, HTTP error | L7 (Application) | Auth failure, bad cert, app crash | Check credentials, TLS config, app logs |
Change Window Decision Matrix¶
| Change Type | Risk Level | Recommended Window | Rollback Plan |
|---|---|---|---|
| Ingress external/internal toggle | Medium | Low-traffic period | Restore prior ingress type and re-validate FQDN |
| Subnet/route/NSG update | High | Planned maintenance window | Reapply last known-good network policy from IaC |
| Private DNS zone link update | High | Planned maintenance window | Re-link previous zone and flush DNS clients |
| WAF or gateway routing change | Medium | Controlled release window | Revert listener/rule set and retest /health |
Validate from caller network context
Always run connectivity checks from the same network path as the failing caller (same VNet/subnet/peering boundary). Control-plane success does not guarantee data-plane reachability.
Do not combine multiple network changes in one window
Applying DNS, NSG, UDR, and ingress changes together makes root-cause isolation significantly harder during incidents.
Troubleshooting¶
Requests time out¶
- Confirm ingress type matches caller location.
- Verify application port and
targetPortalignment. - Check NSG or route table updates affecting VNet path.
az network watcher test-connectivity \
--resource-group "$RG" \
--source-resource "/subscriptions/<subscription-id>/resourceGroups/$RG/providers/Microsoft.App/containerApps/$APP_NAME" \
--dest-address "<dependency-hostname>" \
--dest-port 443
Advanced Topics¶
- Use internal ingress plus Application Gateway for centralized WAF.
- Define egress allow-list controls with Azure Firewall or NVA.
- Standardize DNS and naming for service-to-service resilience.