How to add existing route table to subnet - azure

I am new to bicep and I am trying to attach an existing UDR named "udr-test" to 2 subnets, unfortunately with no luck.
This is my template that work fine but without UDR configuration:
var addressSpace = [
'10.0.0.0/16'
]
var subnets = [
{
name: 'Subnet1'
subnetPrefix: '10.0.2.0/24'
}
{
name: 'Subnet2'
subnetPrefix: '10.0.3.0/24'
}
]
resource VNET 'Microsoft.Network/virtualNetworks#2021-02-01' existing = {
name: 'vnet-test'
}
#batchSize(1)
resource Subnets 'Microsoft.Network/virtualNetworks/subnets#2020-11-01' = [for (sn, index) in subnets: {
name: sn.name
parent: VNET
properties: {
addressPrefix: sn.subnetPrefix
}
}]
Do you know how I can modify the template to add the UDR as well?

There is routeTable property on the subnet resource (see documentation):
// reference to existing route table
resource routeTable 'Microsoft.Network/routeTables#2022-01-01' existing = {
name: 'udr-test'
}
#batchSize(1)
resource Subnets 'Microsoft.Network/virtualNetworks/subnets#2020-11-01' = [for (sn, index) in subnets: {
name: sn.name
parent: VNET
properties: {
addressPrefix: sn.subnetPrefix
routeTable:{
id: routeTable.id // assign the route table
}
}
}]

Related

Assign NSG to VNet subnet using Bicep template

I want to add an existing NSG to existing VNet subnet.
I tried doing it this way:
#description('Name of nsg')
param nsgName string
#description('Name of vnet')
param vnetName string
#description('Name of subnet')
param subnetName string
resource nsg 'Microsoft.Network/networkSecurityGroups#2022-01-01' existing = {
name: nsgName
}
resource subnet 'Microsoft.Network/virtualNetworks/subnets#2022-01-01' existing = {
name: '${vnetName}/${subnetName}'
}
resource nsgAttachment 'Microsoft.Network/virtualNetworks/subnets#2022-01-01' = {
name: '${vnetName}/${subnetName}'
properties: {
addressPrefix: subnet.properties.addressPrefix
networkSecurityGroup: {
id: nsg.id
}
}
}
Unfortunately, I can't pass the review/validation on Azure portal. It says that:
{"code":"InvalidTemplate","message":"Deployment template validation failed: 'Circular dependency detected on resource: '/subscriptions/xxxxxxxxx-02eaf5d20f25/resourceGroups/bicepRG/providers/Microsoft.Network/virtualNetworks/myVnetName/subnets/api'. Please see https://aka.ms/arm-template/#resources for usage details.'."}
How to assign a NSG to existing VNet subnet, or how to get rid of this Circular dependency error?
You will have to use a module to update the subnet:
// update-subnet.bicep
param vnetName string
param subnetName string
param properties object
resource subnet 'Microsoft.Network/virtualNetworks/subnets#2022-01-01' = {
name: '${vnetName}/${subnetName}'
properties: properties
}
From you main, you could invoke it like that:
// main.bicep
param nsgName string = 'thomastest-nsg2'
param vnetName string = 'thomastest-vnet'
param subnetName string = 'subnet1'
// Reference to nsg
resource nsg 'Microsoft.Network/networkSecurityGroups#2022-01-01' existing = {
name: nsgName
}
// Get existing subnet
resource subnet 'Microsoft.Network/virtualNetworks/subnets#2022-01-01' existing = {
name: '${vnetName}/${subnetName}'
}
// Update the subnet
module attachNsg 'update-subnet.bicep' = {
name: 'update-vnet-subnet-${vnetName}-${subnetName}'
params: {
vnetName: vnetName
subnetName: subnetName
// Update the nsg
properties: union(subnet.properties, {
networkSecurityGroup: {
id: nsg.id
}
})
}
}

How do I defined subnets in Bicep such that the parent Vnet has a reference and that I can dependOn the subnet deployment?

I have a situation where I need to define my subnets in the properties.subnets field of the parent virtual network otherwise I get the 'InUseSubnetCannotBeDeleted' problem
Option 1 - Defined inline
However if I define my subnets directly in the properties.subnet array (see below) then they are not created as children and I cannot seem to create a reference them as a resource for when I want to create a dependsOn reference for another resource.
resource virtualNetwork 'Microsoft.Network/virtualNetworks#2021-08-01' = {
// ... other fields
properties: {
subnets: [
// How can I get a reference to these that I can 'dependOn'?
{
name: 'subnet-1'
// ... other fields
}
{
name: 'subnet-2'
// ... other fields
}
]
}
}
Option 2 - Defined separately
resource virtualNetwork 'Microsoft.Network/virtualNetworks#2021-08-01' = {
// ... other fields
properties: {
subnets: [
subnet1 // Gives a circular reference error
]
}
}
resource subnet1 'Microsoft.Network/virtualNetworks/subnets#2021-08-01' = {
parent: virtualNetwork
name: 'subnet-1'
// ... other fields
}
I have tried defining the subnets as separate resources and then reference the resources in the properties.subnet array but, since subnets need a reference to the parent virtual network proeprty, Bicep complains about a circular reference.
It seems that ARM templates can use textual references using the name of the subnet in properties.subnets whcih could get around the circular reference, however Bicep does not allow this.
So how do I defined my subnets so that I can simulteneously satisfy the virtual network's required to have a reference to the subnets in properties.subnets as well as be able to have a resource reference that I can use in dependsOn clauses?
Maybe this will work. Bicep builds it without errors, but I have not tried to deploy it.
resource virtualNetwork 'Microsoft.Network/virtualNetworks#2021-08-01' = {
name: 'myvnet'
location: 'swedencentral'
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/20'
]
}
subnets: [
{
name: 'subnet-1'
properties: {
addressPrefix: '10.0.0.0/24'
}
}
]
}
}
resource subnet 'Microsoft.Network/virtualNetworks/subnets#2022-01-01' existing = {
name: 'myvnet/subnet-1'
scope: resourceGroup()
}
resource storage 'Microsoft.Storage/storageAccounts#2021-09-01' = {
name: 'mystorage'
location: 'swedencentral'
dependsOn: [
subnet
]
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
}

How to reference an object in an array of objects using Bicep

I am trying to output the referenceId of each subnet in a module that creates a virtual network with 4 subnets. I can get the first one, [0], but when I try output the others, [1], [2], [3] the deployment fails and throws the error:
The language expression property array index "1" is out of bounds
Below is the code to create the virtualNetwork and the subnets:
resource virtualNetwork 'Microsoft.Network/virtualNetworks#2018-11-01' = {
name: vNetName
location: location
tags: tags
properties: {
addressSpace: {
addressPrefixes: [
addressPrefix
]
}
subnets: subnets
}
}
subnets is a variable of type array:
var subnets = [
{
name: mgmtSubnetName
properties: {
addressPrefix: mgmtSubnetAddressPrefix
}
}
{
name: intSubnetName
properties: {
addressPrefix: intSubnetAddressPrefix
}
}
{
name: extSubnetName
properties: {
addressPrefix: extSubnetAddressPrefix
}
}
{
name: vdmsSubnetName
properties: {
addressPrefix: vdmsSubnetAddressPrefix
}
}
]
When I use the output line below, it returns and array that has 4 objects...one for each subnet created:
output subnets array = virtualNetwork.properties.subnets
Each object has the format below:
{
"name":"<value>",
"id":"<value>",
"etag":"<value>",
"properties":{
"provisioningState":"Succeeded",
"addressPrefix":"<value>",
"ipConfigurations":[
{
"id":"<value>"
}
],
"delegations":[]
},
"type":"Microsoft.Network/virtualNetworks/subnets"
}
When I use the output line below, it returns the first object in the subnets array:
output subnet1 object = virtualNetwork.properties.subnets[0]
When I use the output line below, it returns the resourceId of the first subnet:
output subnet1 string = virtualNetwork.properties.subnets[0].id
I am unable to retrieve the other objects in the array using indexes 1, 2, or 3.
I have also tried the resourceId function (example below) but the behavior is exactly the same for indexes 1, 2, or 3:
output subnet1Id string = resourceId('Microsoft.Network/VirtualNetworks/subnets', name, subnets[0].name)
You can use the below bicep template to deploy the vnet and subnets and output the subnets and subnet id's like below :
var subnets = [
{
name: 'vm-subnet'
properties: {
addressPrefix:'10.0.0.0/24'
}
}
{
name: 'webapp-subnet'
properties: {
addressPrefix:'10.0.1.0/24'
}
}
{
name: 'appgw-subnet'
properties: {
addressPrefix:'10.0.2.0/24'
}
}
{
name: 'bastion-subnet'
properties: {
addressPrefix:'10.0.3.0/24'
}
}
]
resource virtualNetwork 'Microsoft.Network/virtualNetworks#2018-11-01' = {
name: 'ansuman-vnet'
location: 'east us'
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: subnets
}
}
output subnets array = [for (name, i) in subnets :{
subnets : virtualNetwork.properties.subnets[i]
}]
output subnetids array = [for (name, i) in subnets :{
subnets : virtualNetwork.properties.subnets[i].id
}]
output subnetappgw string = virtualNetwork.properties.subnets[2].id
output webappsubnet object = virtualNetwork.properties.subnets[1]
Outputs:
Note: I am using the latest Bicep version i.e. Bicep CLI version 0.4.1124

How to select and add multiple subnets of a VNet in networking section of an azure eventHub using bicep

How to select and add multiple subnets of a VNet in the networking section of an azure eventHub resource using azure bicep.
// Create an event hub namespace
var eventHubNamespaceName = 'evhns-demo1436'
resource eventHubNamespace 'Microsoft.EventHub/namespaces#2021-01-01-preview' = {
name: eventHubNamespaceName
location: resourceGroup().location
sku: {
name: 'Standard'
tier: 'Standard'
capacity: 1
}
properties: {
zoneRedundant: true
}
}
// Create an event hub inside the namespace
var eventHubName = 'evh-demo1436'
resource eventHubNamespaceName_eventHubName 'Microsoft.EventHub/namespaces/eventhubs#2021-01-01-preview' = {
parent: eventHubNamespace
name: eventHubName
properties: {
messageRetentionInDays: 7
partitionCount: 1
}
}
// Grant Listen and Send on our event hub
resource eventHubNamespaceName_eventHubName_ListenSend 'Microsoft.EventHub/namespaces/eventhubs/authorizationRules#2021-01-01-preview' = {
parent: eventHubNamespaceName_eventHubName
name: 'ListenSend'
properties: {
rights: [
'Listen'
'Send'
]
}
dependsOn: [
eventHubNamespace
]
}
resource testVnet 'Microsoft.Network/virtualNetworks#2021-03-01' existing = {
name: 'testvnet'
}
resource testsubnet 'Microsoft.Network/virtualNetworks/subnets#2021-03-01' existing = {
parent: testVnet
name: 'testsubnet'
}
resource enHubVnetRule 'Microsoft.EventHub/namespaces/virtualnetworkrules#2018-01-01-preview' = {
name: 'vnetName'
parent: eventHubNamespace
properties: {
virtualNetworkSubnetId: testsubnet.id
}
}
With above code I can only add one particular subnet of a VNet to the VNet entry of azure EventHub resource in networking section using azure bicep.
How do I fetch all subnets of a VNet and add/select them all to the VNet entry of azure EventHub resource in networking section using azure bicep.
You have to use for loop for the subnet block and virtual-network rule block like below:
// Create an event hub namespace
param eventHubNamespaceName string = 'evhns-demo1436'
resource eventHubNamespace 'Microsoft.EventHub/namespaces#2021-01-01-preview' = {
name: eventHubNamespaceName
location: resourceGroup().location
sku: {
name: 'Standard'
tier: 'Standard'
capacity: 1
}
properties: {
zoneRedundant: true
}
}
// Create an event hub inside the namespace
param eventHubName string = 'evh-demo1436'
resource eventHubNamespaceName_eventHubName 'Microsoft.EventHub/namespaces/eventhubs#2021-01-01-preview' = {
parent: eventHubNamespace
name: eventHubName
properties: {
messageRetentionInDays: 7
partitionCount: 1
}
}
// Grant Listen and Send on our event hub
resource eventHubNamespaceName_eventHubName_ListenSend 'Microsoft.EventHub/namespaces/eventhubs/authorizationRules#2021-01-01-preview' = {
parent: eventHubNamespaceName_eventHubName
name: 'ListenSend'
properties: {
rights: [
'Listen'
'Send'
]
}
dependsOn: [
eventHubNamespace
]
}
param subnets array =[
'test'
'mysubnet'
]
param vnetname string = 'test-ansuman'
resource testVnet 'Microsoft.Network/virtualNetworks#2021-03-01' existing = {
name: vnetname
}
resource testsubnet 'Microsoft.Network/virtualNetworks/subnets#2021-03-01' existing =[for subnet in subnets : {
parent: testVnet
name: subnet
}]
resource enHubVnetRule 'Microsoft.EventHub/namespaces/virtualnetworkrules#2018-01-01-preview' = [for (subnet,i) in subnets :{
name: '${vnetname}-${subnet}'
parent: eventHubNamespace
properties: {
virtualNetworkSubnetId:testsubnet[i].id
}
}]
Output:

How can I create an array of subnets on an existing vnet using Bicep?

In my bicep file I obtain a reference to the existing vnet like this:
resource existingVNET 'Microsoft.Network/virtualNetworks#2021-02-01' existing = {
name: 'the-existing-vnet'
}
I have tried to include multiple (four to be exact) resource statements for each of the subnets like this:
resource subnetPbdResource 'Microsoft.Network/virtualNetworks/subnets#2020-11-01' = {
parent: existingVNET
name: 'first-snet'
...
}
resource subnetPbdResource 'Microsoft.Network/virtualNetworks/subnets#2020-11-01' = {
parent: existingVNET
name: 'second-snet'
...
}
...however, when I run this (using az deployment group create ...) I get an error: with code AnotherOperationInProgress. One random (it seems) subnet has been created under the vnet.
I've also tried to define an array of subnets like this:
var subnets = [
{
name: 'api'
subnetPrefix: '10.144.0.0/24'
}
{
name: 'worker'
subnetPrefix: '10.144.1.0/24'
}
]
...but I cannot find a way to assign the existing vnet with the subnets array. .properties.subnets is not accessible for the existing vnet resource it seems.
Any tip appreciated!
It seems that ARM gets tangled up when it tries to deploy more than one subnet resource at the same time.
You can use dependsOn to make sure the subnets get created one after another:
resource existingVNET 'Microsoft.Network/virtualNetworks#2021-02-01' existing = {
name: 'the-existing-vnet'
}
resource subnetPbdResource 'Microsoft.Network/virtualNetworks/subnets#2021-02-01' = {
name: 'first-snet'
parent: existingVNET
properties: {
addressPrefix: '10.0.1.0/24'
}
}
resource subnetPbdResource2 'Microsoft.Network/virtualNetworks/subnets#2021-02-01' = {
name: 'second-snet'
parent: existingVNET
properties: {
addressPrefix: '10.0.2.0/24'
}
dependsOn: [
subnetPbdResource
]
}
resource subnetPbdResource3 'Microsoft.Network/virtualNetworks/subnets#2021-02-01' = {
name: 'third-snet'
parent: existingVNET
properties: {
addressPrefix: '10.0.3.0/24'
}
dependsOn: [
subnetPbdResource2
]
}
I also got a great answer on Bicep github discussion
Basically it boils down to building an array of subnets, use #batchSize(1) to ensure serial creation of subnets (I guess this achieves the same as using dependsOn in answer from #Manuel Batsching) and pass the subnet array as parameter to Resource "create subnet statement".
Obvious advantage: no duplicate code to create subnet

Resources