Azure / Azure/arm-template-whatif
What-if falsely reports subnets + peerings will be deleted if they aren't present in Bicep file
- Dominant language
- HTML
- Stars
- 101
- Forks
- 21
- Avg merge
- 3h 35m
- Merged PRs (30d)
- 1
Description
**Bicep version**
Bicep CLI version 0.46.1 (545b338e2c)
**Describe the bug**
When updating a virtual network via Bicep, what-if falsely reports that subnets and peerings will be deleted if they are not defined in the Bicep file being deployed. This occurs even if the subnets are defined as separate child resources in the file I am deploying.
For example, given:
- A bicep file which defines a virtual network and 2 subnets, which has been deployed once already. We are deploying the file again (with no changes to the Bicep code for the vnet/subnets).
- A new subnet, a separate vnet, and peering between the 2 vnets, all created outside of the 1st Bicep file (the way these are created is unimportant - can be via the Portal, via other Bicep files, via Terraform etc.)
What I expect: `az deployment group what-if` will ignore the other subnet and peering.
What happens: `az deployment group what-if` reports that the peering and new subnet will be deleted. Deploying the file doesn't actually touch them (which is what I expect - given that I am defining the subnets as separate resources, and a PUT on a virtual network with no subnets in the body should leave the subnets alone, as per https://techcommunity.microsoft.com/blog/azurenetworkingblog/azure-virtual-network-now-supports-updates-without-subnet-property/4067952). This is what the output looks like from `az deployment group what-if`:
```
Scope: /subscriptions/9fb3a946-ec8f-45e1-b1f2-0481f480ae4d/resourceGroups/rg-subnetdeletiontest
~ Microsoft.Network/virtualNetworks/vnet-subnetdeletiontest [2025-07-01]
- properties.privateEndpointVNetPolicies: "Disabled"
- properties.virtualNetworkPeerings: [
0:
name: "vnet-subnetdeletiontest-layer1-to-layer2"
properties.allowForwardedTraffic: false
properties.allowGatewayTransit: false
properties.allowVirtualNetworkAccess: true
properties.doNotVerifyRemoteGateways: false
properties.peerCompleteVnets: true
properties.peeringSyncLevel: "FullyInSync"
properties.remoteAddressSpace.addressPrefixes: [
0: "10.0.32.0/19"
]
properties.remoteVirtualNetwork.id: "/subscriptions/9fb3a946-ec8f-45e1-b1f2-0481f480ae4d/resourceGroups/rg-subnetdeletiontest/providers/Microsoft.Network/virtualNetworks/vnet-subnetdeletiontest-layer2"
properties.remoteVirtualNetworkAddressSpace.addressPrefixes: [
0: "10.0.32.0/19"
]
properties.useRemoteGateways: false
]
~ properties.subnets: [
- 2:
name: "subnet3"
properties.addressPrefix: "10.0.2.0/24"
properties.defaultOutboundAccess: false
properties.privateEndpointNetworkPolicies: "Disabled"
properties.privateLinkServiceNetworkPolicies: "Enabled"
]
x properties.subnets[0].type: "Microsoft.Network/virtualNetworks/subnets"
x properties.subnets[1].type: "Microsoft.Network/virtualNetworks/subnets"
~ Microsoft.Network/virtualNetworks/vnet-subnetdeletiontest/subnets/subnet1 [2025-07-01]
- properties.defaultOutboundAccess: false
~ properties.privateEndpointNetworkPolicies: "Disabled" => "Enabled"
~ Microsoft.Network/virtualNetworks/vnet-subnetdeletiontest/subnets/subnet2 [2025-07-01]
- properties.defaultOutboundAccess: false
~ properties.privateEndpointNetworkPolicies: "Disabled" => "Enabled"
* Microsoft.Network/virtualNetworks/vnet-subnetdeletiontest-layer2
Resource changes: 3 to modify, 1 to ignore.
```
**To Reproduce**
Steps to reproduce the behavior:
1. Deploy the following files in order to a resource group:
```
// layer-1.bicep
targetScope = 'resourceGroup'
resource network 'Microsoft.Network/virtualNetworks@2025-07-01' = {
name: 'vnet-subnetdeletiontest'
location: resourceGroup().location
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/19'
]
}
}
}
resource subnet1 'Microsoft.Network/virtualNetworks/subnets@2025-07-01' = {
name: 'subnet1'
parent: network
properties: {
addressPrefix: '10.0.0.0/24'
}
}
resource subnet2 'Microsoft.Network/virtualNetworks/subnets@2025-07-01' = {
name: 'subnet2'
parent: network
properties: {
addressPrefix: '10.0.1.0/24'
}
dependsOn: [
subnet1
]
}
```
```
// layer-2.bicep
// Create a virtual network and peer it to the one we defined in layer-1.bicep
targetScope = 'resourceGroup'
resource network1 'Microsoft.Network/virtualNetworks@2025-07-01' existing = {
name: 'vnet-subnetdeletiontest'
}
resource network2 'Microsoft.Network/virtualNetworks@2025-07-01' = {
name: 'vnet-subnetdeletiontest-layer2'
location: resourceGroup().location
properties: {
addressSpace: {
addressPrefixes: [
'10.0.32.0/19'
]
}
}
}
resource peering1 'Microsoft.Network/virtualNetworks/virtualNetworkPeerings@2025-07-01' = {
name: 'vnet-subnetdeletiontest-layer2-to-layer1'
parent: network2
properties: {
allowVirtualNetworkAccess: true
remoteVirtualNetwork: {
id: resourceId('Microsoft.Network/virtualNetworks', 'vnet-subnetdeletiontest')
}
}
}
resource peering2 'Microsoft.Network/virtualNetworks/virtualNetworkPeerings@2025-07-01' = {
name: 'vnet-subnetdeletiontest-layer1-to-layer2'
parent: network1
properties: {
allowVirtualNetworkAccess: true
remoteVirtualNetwork: {
id: resourceId('Microsoft.Network/virtualNetworks', 'vnet-subnetdeletiontest-layer2')
}
}
dependsOn: [
peering1
]
}
```
```
// layer-3.bicep
// Create an additional subnet in the virtual network we defined in layer-1.bicep
targetScope = 'resourceGroup'
resource network 'Microsoft.Network/virtualNetworks@2025-07-01' existing = {
name: 'vnet-subnetdeletiontest'
}
resource subnet3 'Microsoft.Network/virtualNetworks/subnets@2025-07-01' = {
name: 'subnet3'
parent: network
properties: {
addressPrefix: '10.0.2.0/24'
}
}
```
```
az deployment group create --resource-group rg-subnetdeletiontest --template-file layer-1.bicep --confirm-with-what-if
az deployment group create --resource-group rg-subnetdeletiontest --template-file layer-2.bicep --confirm-with-what-if
az deployment group create --resource-group rg-subnetdeletiontest --template-file layer-3.bicep --confirm-with-what-if
```
2. Run the layer 1 file again:
```
az deployment group create --resource-group rg-subnetdeletiontest --template-file layer-1.bicep --confirm-with-what-if
```
The what-if output will show the peering and subnet we created in layers 2 and 3 being deleted, as above.
3. Continue and deploy anyway. The subnet and peering won't actually be removed.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the behavior with layer-1.bicep, layer-2.bicep, and layer-3.bicep, then rerun the shown az deployment group create command for layer 1 with --confirm-with-what-if. Trace how the what-if output handles the externally created subnet and peering. Done means the unchanged layer-1 deployment no longer reports those resources as deleted while preserving the actual deployment behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100