I have an existing vnet and route table in RG1. All other resources are going in RG2.
I am creating a subnet bicep which will be called as a module and it has to be associated with vnet and route table.
subnet bicep
//parameters
//variables
resource vnetRef 'Microsoft.Network/virtualNetworks@2023-09-01' = {
name: vnetId
}
resource subnet 'Microsoft.Network/virtualNetworks/subnets@2023-09-01' = {
name: subnetName
parent: vnetRef
properties: {
addressPrefix: subnetPrefix
routeTable: {
id: routeTableId
}
}
}
output subnetId string = subnet.id
main bicep
resource vnet 'Microsoft.Network/virtualNetworks@2023-09-01' existing = {
name: '${appAcronym}-${subscriptionName}-vnet'
scope: resourceGroup(sharedScopeRG)
}
resource routeTable 'Microsoft.Network/routeTables@2023-09-01' existing = {
name: routeTableName
scope: resourceGroup(sharedScopeRG)
}
module subnetModule '../AnotherRepo/subnet.bicep' = {
name: 'subnetModule'
scope: resourceGroup(rgName)
params: {
name: subnetName
subnetPrefix: subnetAddressSpace
vnetId: vnet.id
routeTableId: routeTable.id
//other params for subnet bicep
}
}
It fails with The template resource '/subscriptions/subid/resourceGroups/RG1/providers/Microsoft.Network/virtualNetworks/myVnet' for type 'Microsoft.Network/virtualNetworks' at line '1' and column '1739' has incorrect segment lengths. A nested resource type must have identical number of segments as its resource name. A root resource type must have segment length one greater than its resource name. Please see https://aka.ms/arm-syntax-resources for usage details.'.
I then passed vnet.name instead of vnet.id when calling subnet bicep and then get the following error: Resource 'myVnet' was disallowed by policy. Error Type: PolicyViolation, Policy Definition Name : Allowed locations, Policy Assignment Name : .
Which means it is trying to create vnet when the subnet module is being called. I have tried multiple ways of referring them but none are working out.
First thing, you should deploy the subnets inside the vnet resource. Otherwise if you rerun the vnet module, the existing subnets not defined in the vnet module will be destroy (see related post).
in your subnet module, you need to use the existing
keyword to reference the existing vnet:
// subnet.bicep
param vnetName string
param subnetName string
param subnetPrefix string
param routeTableId string
resource vnetRef 'Microsoft.Network/virtualNetworks@2023-09-01' existing = {
name: vnetName
}
resource subnet 'Microsoft.Network/virtualNetworks/subnets@2023-09-01' = {
parent: vnetRef
name: subnetName
properties: {
addressPrefix: subnetPrefix
routeTable: {
id: routeTableId
}
}
}
output subnetId string = subnet.id
When invoking the subnet module from your main file, the scope of the module has to be the scope of the vnet resource group:
param appAcronym string
param subscriptionName string
param sharedScopeRG string
param routeTableName string
param subnetName string
param subnetAddressSpace string
resource vnet 'Microsoft.Network/virtualNetworks@2023-09-01' existing = {
name: '${appAcronym}-${subscriptionName}-vnet'
scope: resourceGroup(sharedScopeRG)
}
resource routeTable 'Microsoft.Network/routeTables@2023-09-01' existing = {
name: routeTableName
scope: resourceGroup(sharedScopeRG)
}
module subnetModule 'subnet.bicep' = {
name: 'subnetModule'
scope: resourceGroup(sharedScopeRG) // scope should be the scope of the vnet resource group
params: {
subnetName: subnetName
vnetName: vnet.name
subnetPrefix: subnetAddressSpace
routeTableId: routeTable.id
}
}