Egress Control¶
Control outbound traffic from Container Apps.
Default Behavior¶
By default, Container Apps can access: - Public internet - Azure services via public endpoints - Resources in the same VNet (if VNet integrated)
Uncontrolled egress increases data exfiltration risk
Production workloads should define explicit outbound paths and approved destinations, especially when handling regulated or sensitive data.
Egress Strategy Comparison¶
| Strategy | Primary Goal | Trade-off | Typical Fit |
|---|---|---|---|
| Default outbound | Fast setup | Minimal governance | Dev/test environments |
| UDR + Azure Firewall | Domain/IP filtering and inspection | Higher complexity and cost | Regulated production workloads |
| NAT Gateway | Static outbound IP for allow-lists | No L7 filtering by itself | SaaS allow-list integrations |
User-Defined Routes (UDR)¶
Route outbound traffic through Azure Firewall or NVA:
flowchart LR
subgraph VNet [Virtual Network]
subgraph Subnet [CAE Subnet]
APP[Container App]
end
subgraph FWSubnet [AzureFirewallSubnet]
FW[Azure Firewall]
end
subgraph RT [Route Table]
R[0.0.0.0/0 -> Firewall IP]
end
end
subgraph Internet [Public Internet]
EXT[Public API]
end
APP -- 1. Outbound Request --> RT
RT -- 2. Next Hop --> FW
FW -- 3. Policy Check --> EXT resource routeTable 'Microsoft.Network/routeTables@2023-05-01' = {
name: 'rt-containerapp'
location: location
properties: {
routes: [
{
name: 'default-route'
properties: {
addressPrefix: '0.0.0.0/0'
nextHopType: 'VirtualAppliance'
nextHopIpAddress: firewallPrivateIp
}
}
]
}
}
Azure Firewall Rules¶
Allow required outbound traffic:
NAT Gateway Architecture¶
flowchart TD
subgraph VNet [Virtual Network]
subgraph Subnet [CAE Subnet]
APP[Container App]
end
NGW[NAT Gateway]
PIP[Public IP Address]
end
subgraph Internet [Public Internet]
EXT[Public Dependency]
end
APP -- 1. Outbound Traffic --> NGW
NGW -- 2. Source NAT (PIP) --> EXT resource firewallPolicy 'Microsoft.Network/firewallPolicies@2023-05-01' = {
name: 'fw-policy'
properties: {
sku: { tier: 'Standard' }
}
}
Azure Firewall Rules¶
Allow required outbound traffic:
resource firewallPolicy 'Microsoft.Network/firewallPolicies@2023-05-01' = {
name: 'fw-policy'
properties: {
sku: { tier: 'Standard' }
}
}
resource appRuleCollection 'Microsoft.Network/firewallPolicies/ruleCollectionGroups@2023-05-01' = {
parent: firewallPolicy
name: 'container-apps-rules'
properties: {
priority: 100
ruleCollections: [
{
ruleCollectionType: 'FirewallPolicyFilterRuleCollection'
name: 'allow-external-apis'
priority: 100
action: { type: 'Allow' }
rules: [
{
ruleType: 'ApplicationRule'
name: 'allow-jsonplaceholder'
protocols: [{ protocolType: 'Https', port: 443 }]
targetFqdns: ['jsonplaceholder.typicode.com']
sourceAddresses: ['10.0.0.0/23']
}
]
}
]
}
}
NAT Gateway for Static Outbound IP¶
Assign static IP for outbound traffic:
resource natGateway 'Microsoft.Network/natGateways@2023-05-01' = {
name: 'nat-containerapp'
location: location
sku: { name: 'Standard' }
properties: {
publicIpAddresses: [{ id: publicIp.id }]
}
}
resource subnet 'Microsoft.Network/virtualNetworks/subnets@2023-05-01' = {
name: 'snet-containerapp'
properties: {
addressPrefix: '10.0.0.0/23'
natGateway: { id: natGateway.id }
}
}
Combine NAT and firewall when needed
Use NAT Gateway for predictable source IP and Azure Firewall for destination governance when both compliance and partner allow-list requirements exist.
Verify Outbound IP¶
import requests
@app.route('/api/my-ip')
def my_ip():
# Use standard service to verify public outbound IP
response = requests.get('https://api.ipify.org?format=json')
return response.json() # Returns NAT Gateway's public IP