Nov 11 2020 08:32 AM - edited Nov 11 2020 08:53 AM
Hi All,
I am trying to create Multiple NSG with multiple rules associate with subnets. Can anyone give me the Template file which is used as single Template file for Multiple NSG.
Attached is the current files used by me for creating NSG.
The problem in the below script is, It is not creating more than 2 NSG's. So that i am expecting to have a single Template and parameter file to create multiple NSG's. More likely to use copy loops.
Template File:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
"contentVersion": "1.0.0.1",
"parameters": {
"virtualNetworkName": {
"type": "String"
},
"networkSecurityGroupName1": {
"type": "String"
},
"subnetName1": {
"type": "String"
},
"networkSecurityGroupRules1": {
"type": "Array"
},
"networkSecurityGroupName2": {
"type": "String"
},
"subnetName2": {
"type": "String"
},
"networkSecurityGroupRules2": {
"type": "Array"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2018-03-01",
"name": "[parameters('networkSecurityGroupName1')]",
"location": "[resourceGroup().location]",
"properties": {
"securityRules": "[parameters('networkSecurityGroupRules1')]"
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-08-01",
"name": "apply-nsg-to-subnet1",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName1'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2018-03-01",
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName1'))]",
"location": "[resourceGroup().location]",
"properties": {
"addressPrefix": "[reference(resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName1')), '2018-03-01').addressPrefix]",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName1'))]"
}
}
}
]
}
},
"resourceGroup": "[resourceGroup().name]"
},
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2018-03-01",
"name": "[parameters('networkSecurityGroupName2')]",
"location": "[resourceGroup().location]",
"properties": {
"securityRules": "[parameters('networkSecurityGroupRules2')]"
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-08-01",
"name": "apply-nsg-to-subnet2",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName2'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2018-03-01",
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName2'))]",
"location": "[resourceGroup().location]",
"properties": {
"addressPrefix": "[reference(resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName2')), '2018-03-01').addressPrefix]",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName2'))]"
}
}
}
]
}
},
"resourceGroup": "[resourceGroup().name]"
}
],
"outputs": {}
}
Nov 17 2020 12:35 PM
SolutionHi!
I've put together a template for you that solves your problem using copy loops for both the NSGs and the subnet association. You can find it here: https://gist.github.com/StefanIvemo/31cda6faa214824b2049a1e98f0e279b
I've created a parameter called NSGs of the type array in the template. Take a look at the example parameter file and adjust it to your needs. All you have to do is add/remove objects to the array and fill in NSGName, SubnetName and your SecurityRules.
The template will first deploy all the NSGs and then do a nested deployment to do the subnet association.
Good luck with your deployment!
Nov 19 2020 01:59 AM
Fantastic, NSG is working Expected. In the same way i need to create Route Tables and Number of Routes in each route tables. Can you please help me on that ??
Nov 19 2020 02:04 AM
@StefanIvem,
Can you please help me to create ARM for Route Tables associate with existing Subnets.
Inside Each Routes i need numbers of Routes should be attached with properties.
Thanks,
Vignesh
Nov 19 2020 03:38 AM
You can continue with the template I provided. Just add a property for routes to the parameter file for each of the objects in the array, the same way as for securityRules. E.g. "routes": [], and add your custom routes to it.
Then create a copy loop to create Microsoft.Network/routeTables just like the one for NSGs but modify the properties to work with the Route Table resource.
In the nested deploy where the NSG is associated with the subnet you add the routeTable property.
Good luck!
Nov 19 2020 05:39 AM
Hi,
Thanks for the quick update.....
I have modified as per your request but deployment is failing. Below is the Modified Template and Para files.
Nov 19 2020 06:27 AM
I've updated the NSG template provided earlier with route tables as well. You can find it here:
https://gist.github.com/StefanIvemo/1862a1401fa982cc8f124a6148eda5f5
You can now deploy NSGs and Route Tables at the same time and update the subnets.
Hope it works for you!
Dec 01 2020 05:15 AM
Hi Stefan,
This is working as expected, Is it possible to create Multiple Routes inside One Route Table using this Same template and para files.
Can you please help me to create Multiple Routes inside route Table.
https://gist.github.com/StefanIvemo/1862a1401fa982cc8f124a6148eda5f5
I am trying to add two Routes inside one route table as below but i am not able to get it, Can you please help on this.
Regards,
Vignesh
Dec 01 2020 05:54 AM
You can add additional routes by adding another route object in the routes array in the parameter file:
Dec 04 2020 03:11 AM
Hi Stefan,
It is working good, But it is mandate to create RouteTable and Routes every time while using this script>
Is it possible to give options that Routes and Route Tables needs to create only when needed.
If i give null value or does not give Route and Route Tables along with NSG it is not creating.
Can you please help me on this.
Regards,
Vignesh
Dec 13 2020 01:29 AM
Dec 16 2020 12:22 AM
Hi,
I do not need Route Table and Routes created at every time, I only needed to create when i needs.
But here it is mandate to create everytime which i do not need.
Regards,
Vignesh
Dec 17 2020 12:41 AM
Dec 17 2020 12:42 AM
Dec 17 2020 06:28 AM
In my opinion a subnet should always be created with a route table and NSG. If you don't need any custom routes just edit the parameter file and set the following properties for the subnets where you don't need any custom routing. With no routes and disableBgpRoutePropagation set to false the subnet will use the default routing in Azure even with a route table associated to the subnet.
"disableBgpRoutePropagation": false,
"routes": []
If/when the time comes to add a custom route to the subnet, the route table is there and you can just inject the routes to it.
Dec 21 2020 02:55 AM
Hi Stefan,
Yes, From the Below point i can understand that Route table will create and creating Routes is our wish. But i do not need to create "Route Table" every time when i am running the script.
Example:
I tried to run the script below. In that i have removed "RouteName" and for routes i have given [], But without "RouteName" the script is not running. So i need to run the script without Route Table creation. Only i need to give Route Name when i need Route Table. Is that possible. Pls help me !!!
Below I have removed RouteName but it is throwing error. I need to run without Creating RouteTable
{
"properties": {
"NSGName": "NSG03",
"SubnetName": "sub03",
"RouteName": "I Do not need this property"
"securityRules": [
{
"name": "Inbound_Allow_Http",
"properties": {
"description": "Allow inbound http traffic",
"protocol": "TCP",
"sourcePortRange": "*",
"sourceAddressPrefix": "*",
"destinationPortRange": "80",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 4096,
"direction": "Inbound"
}
}
],
"disableBgpRoutePropagation": false,
"routes": []
}
]
}
}
]
}
}
}
Dec 23 2020 12:45 AM
Hi Stefan,
Any update on this please, The point is we don't need to create Route tables while running the script. If we need Route table we will add Route Property in parameter files. But while doing with this script it is throwing error. I am not sure how to modify Template file accordingly !!!
Vignesh
Jan 04 2021 12:28 AM
Hi Stefan,
Any update on this please, The point is we don't need to create Route tables while running the script. If we need Route table we will add Route Property in parameter files. But while doing with this script it is throwing error. I am not sure how to modify Template file accordingly !!!
Vignesh
Jan 05 2021 11:52 PM
Hi Stefan,
The main aim is we don't need to create Route tables while running the script. If we need Route table we will add Route Property in parameter files. But while doing with this script it is throwing error. I am not sure how to modify Template file accordingly !!!
For example if i am running this script now I need to give names of NSG and Route tables as Mandate. If i will not give the route name it is throwing error. So i need to change this, while creating NSG's if needed i need to create Route table or else i will not give the names of Route Table Name as input.
Below is the para i have modified. In first property i am creating 1 NSG and 1 Route and in second property i need only NSG, so i am not giving Route Table Name. But this is not working as it is throwing template error.
"SubnetInfo": {
"value": [
{
"properties": {
"NSGName": "NSG01",
"SubnetName": "sub01",
"RouteName": "RT01",
"securityRules": [
{
"name": "Inbound_Deny_All",
"properties": {
"description": "Deny all inbound traffic",
"protocol": "*",
"sourcePortRange": "*",
"sourceAddressPrefix": "*",
"destinationPortRange": "*",
"destinationAddressPrefix": "*",
"access": "Deny",
"priority": 4096,
"direction": "Inbound"
}
}
],
"disableBgpRoutePropagation": true,
"routes": [
{
"name": "route1",
"properties": {
"addressPrefix": "10.0.0.0/24",
"nextHopType": "VirtualAppliance",
"nextHopIpAddress": "10.0.0.4"
}
}
}
]
}
},
{
"properties": {
"NSGName": "NSG02",
"SubnetName": "sub02",
"securityRules": [
{
"name": "Outbound_Deny_All",
"properties": {
"description": "Deny all inbound traffic",
"protocol": "*",
"sourcePortRange": "*",
"sourceAddressPrefix": "*",
"destinationPortRange": "*",
"destinationAddressPrefix": "*",
"access": "Deny",
"priority": 4096,
"direction": "Outbound"
}
}
],
}
]
}
}
Vignesh
Jan 11 2021 12:19 AM
Hi @vigneshkrcegmailcom !
I've updated the template I've shared before with some additional functionality to be able to achieve the task.
Now if you leave the RouteName property empty in a subnet object in the parameters file no route table will be created for that subnet.
The following changes have been made:
"condition": "[not(empty(parameters('SubnetInfo')[copyIndex()].properties.RouteName))]"
"variables": {
"copy": [
{
"name": "routetableid",
"count": "[length(parameters('SubnetInfo'))]",
"input": {
"id": "[if(empty(parameters('SubnetInfo')[copyIndex('routetableid')].properties.RouteName),'fakeid',resourceId('Microsoft.Network/routeTables', parameters('SubnetInfo')[copyIndex('routetableid')].properties.RouteName))]"
}
}
]
}
"routeTable": "[if(empty(parameters('SubnetInfo')[copyIndex()].properties.RouteName), json('null') ,variables('routetableid')[copyIndex()])]"
https://gist.github.com/StefanIvemo/d9fecb77d9089bd282638aa52a2fffb2
Good luck with your deployment!