Documentation
adrs/045-vnet-service-endpoints.md
ADR-045: VNet Service Endpoints for External Storage Access
Status
Accepted
Context
Container Apps running in a VNet need to access external Azure Storage accounts that have firewall rules enabled. The IoT component's DatalogicBlobProcessor connects to an external storage account (saacsiscorpbbuatdev) that stores camera images from Datalogic devices.
The Problem
When Container Apps in a VNet attempt to access a storage account with firewall rules:
- Without Service Endpoints: Traffic exits via the Container App Environment's static public IP
- Storage Firewall Behavior: The storage account sees the request coming from the public IP, not the VNet
- Result: Even if the VNet/subnet is in the storage account's allowed list, access is denied (403 AuthorizationFailure)
The error manifested as:
Azure.RequestFailedException: This request is not authorized to perform this operation.
Status: 403 (This request is not authorized to perform this operation.)
ErrorCode: AuthorizationFailure
Root Cause
The Container Apps infrastructure subnet was missing the Microsoft.Storage service endpoint. Service endpoints route traffic through Azure's backbone network directly to the storage service, allowing the storage account's VNet firewall rules to recognize the traffic as coming from the allowed subnet.
Decision
Configure the Container Apps infrastructure subnet with the Microsoft.Storage service endpoint in the Dynaplex orchestration infrastructure.
Implementation
// In DynaplexInfrastructureExtensions.cs - AddDynaplexContainerAppEnvironment()
var subnet = new SubnetResource("infrastructureSubnet") {
Parent = vnet,
Name = context.ResourceName(DynaplexContext.AzureAbbreviations.Subnet, "infra"),
AddressPrefix = "10.0.0.0/23",
Delegations = [
new ServiceDelegation {
Name = "containerApps",
ServiceName = "Microsoft.App/environments"
}
],
ServiceEndpoints = [
new ServiceEndpointProperties { Service = "Microsoft.Storage" }
]
};
Consequences
Positive
- Enables External Storage Access: Container Apps can now access storage accounts with VNet firewall rules
- Improved Security: Traffic stays on Azure backbone, never traversing public internet
- Lower Latency: Direct routing to storage service reduces network hops
- Future-Proof: Any component needing external storage access will work automatically
Negative
- Regional Limitation: Service endpoints are regional; cross-region storage access still requires firewall IP rules
- Additional Configuration: External storage accounts must still have the VNet/subnet in their allowed list
Neutral
- No impact on storage accounts without firewall rules (public access still works)
- No impact on the Aspire-managed storage account (uses managed identity, not VNet rules)
Notes
Manual Fix for Existing Deployments
If deploying to an existing environment that doesn't have the service endpoint, run:
az network vnet subnet update \
--resource-group <resource-group> \
--vnet-name <vnet-name> \
--name <subnet-name> \
--service-endpoints Microsoft.Storage
Then restart the affected containers to pick up the network change.
Storage Account Requirements
For external storage accounts to accept traffic from the Container Apps:
- The storage account must have the VNet/subnet in its "Virtual networks" allowed list
- The subnet must have the
Microsoft.Storageservice endpoint enabled - Both conditions must be met - neither alone is sufficient
Related
- ADR-043: Azure Infrastructure Architecture
- ADR-044: PostgreSQL Public Access (similar VNet considerations)