Skip to content

ADR-0004: Deployment Ordering

Status: Accepted | Date: 2026-02-02

In the full scenario (Firewall + VPN Gateway), intermittent deployment failures occurred with InternalServerError on the Azure Firewall. The first attempt failed but retry succeeded.

A race condition when deploying Azure Firewall and VPN Gateway simultaneously:

  1. Both modules depend on the hub VNet (networkingHub)
  2. Both modify the hub VNet (Firewall attaches to AzureFirewallSubnet, VPN Gateway to GatewaySubnet)
  3. Azure Resource Manager attempts concurrent VNet updates
  4. Result: InternalServerError when the VNet is locked by one operation

Serialize Firewall and VPN Gateway deployments using explicit dependsOn.

When both deployFirewall and deployVpnGateway are true (full scenario), the VPN Gateway module waits for the Firewall module to complete:

module vpnGateway 'modules/vpn-gateway.bicep' = if (deployVpnGateway) {
dependsOn: deployFirewall ? [firewall] : []
// ...
}

This adds ~10–15 minutes to the full scenario deployment time but eliminates first-attempt failures.

Positive: 100% first-attempt success rate for the full scenario, no more manual retries needed.

Negative: full scenario takes 40–55 minutes instead of 25–35 minutes. Acceptable trade-off for SMB deployments that run once per customer.