Deploy a VNET & NSG & UDR — Apostolidis Cloud Corner
By: Pantelis Apostolidis
Tags: Iac, Vscode, Mvpbuzz, Azure

Infrastructure as Code | Deploy a VNET with NSG and UDRs

Infrastructure as Code, or just IaC, provides three three main advantages: cost reduction, faster execution and risk reduction, the attributes of the DevOps culture.

Microsoft Azure Resource Manager allows the managing and provisioning of Azure Resources, that can be Virtual Machines, Virtual Networks, Storage Accounts, Apps, SQL Databases and everything that a computer data center includes, through machine-readable definition files, known as JSON templates, without the need of physical hardware configuration or interactive configuration tools.

I am starting a series of posts about building infrastructure with JSON templates.

The tool I use to build my Azure Json templates is the Visual Studio Code. You can download it from https://code.visualstudio.com/ for every platform.

To work with Azure Resource Manager you need the Azure Resource Manager Tools extension. Open the VS Code, go to the Extensions Section, search and install the Azure Resource Manager Tools extension.

The extension is very helpful since it highlights the code, it provides references and intellisense.

At this post I am sharing & explaining my Azure json template for deploying a Virtual Network, a Network Security Group and a Route Table.

You can find and download my working template at my Git account :

https://github.com/proximagr/ARMTemplates/tree/master/VNET-2sub-NSG-UDR

Json Template Guide

Below you can find my template with comments, for better understanding.

{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { //** Define the Virtual Network Name */ "vnetName": { "type": "string", "defaultValue": "Cloud-Corner-VNET", "metadata": { "description": "Cloud Corner VNET" } //** Define the Address Space of the Virtual Network */ }, "vnetAddressPrefix": { "type": "string", "defaultValue": "10.0.0.0/24", "metadata": { "description": "Address prefix" } //** Define the Address Space of the the First Subnet */ }, "subnet1Prefix": { "type": "string", "defaultValue": "10.0.0.0/27", "metadata": { "description": "Subnet 1 Prefix" } //** Define the Name of the the First Subnet */ }, "subnet1Name": { "type": "string", "defaultValue": "Subnet1", "metadata": { "description": "Subnet 1 Name" } //** Define the Address Space of the the Second Subnet */ }, "subnet2Prefix": { "type": "string", "defaultValue": "10.0.0.32/27", "metadata": { "description": "Subnet 2 Prefix" } //** Define the Name of the the First Subnet */ }, "subnet2Name": { "type": "string", "defaultValue": "Subnet2", "metadata": { "description": "Subnet 2 Name" } }, //** Define the Name of the the Network Security Group */ "networkSecurityGroup01Name": { "type": "string", "defaultValue": "Cloud-Corner-NSG-01", "metadata": { "description": "This is the name of the network security group" } }, //** Define the Name of the the First Route Table */ "RouteTable01Name": { "type": "string", "defaultValue": "Cloud-Corner-UDR-01", "metadata": { "description": "Route Table 01 Name." } }, //** Define the Name of the the First Route of the First Route Table */ "Route01Name": { "type": "string", "defaultValue": "To-internet", "metadata": { "description": "Route 01 Name." } }, //** Define the Next Hop Type of the the First Route of the First Route Table */ "Route01NextHopType": { "type": "string", "allowedValues": [ "VirtualNetworkGateway", "VnetLocal", "Internet", "VirtualAppliance", "None" ], "defaultValue": "VirtualAppliance", "metadata": { "description": "Route 01 Next Hop Type." } }, //** Define the Address Prefix of the First Route of the First Route Table */ "Route01AddressPrefix": { "type": "string", "defaultValue": "0.0.0.0/0", "metadata": { "description": "Route 01 Address Prefix." } }, //** If you set "Virtyal Appliance for Next Hop Type, then you need to define the Next Hop IP Address, */ //** meaning the appliance's IP address. Here you define it for the First Route of the First Route Table */ "RT01Route01NextHopIPAddress": { "type": "string", "defaultValue": "10.0.0.40", "metadata": { "description": "Next Hop IP Addess." } }, //** Define the Name of the Second Route Table */ "RouteTable02Name": { "type": "string", "defaultValue": "Cloud-Corner-UDR-02", "metadata": { "description": "Route Table 02 Name." } }, //** Define the Name of the the First Route of the Second Route Table */ "RT02Route01Name": { "type": "string", "defaultValue": "Local-Subnet", "metadata": { "description": "Route Table 02 Route 01 Name." } }, //** Define the Next Hop Type of the the First Route of the Second Route Table */ "RT02Route01NextHopType": { "type": "string", "allowedValues": [ "VirtualNetworkGateway", "VnetLocal", "Internet", "VirtualAppliance", "None" ], "defaultValue": "VnetLocal", "metadata": { "description": "Route 02 Next Hop Type." } }, //** Define the Address Prefix of the the First Route of the Second Route Table */ "RT02Route01AddressPrefix": { "type": "string", "defaultValue": "10.0.0.0/27", "metadata": { "description": "Route Table 02 Route 01 Address Prefix." } }, //** Define the Name of the the Second Route of the Second Route Table */ "RT02Route02Name": { "type": "string", "defaultValue": "To-subnet-1", "metadata": { "description": "Route Table 02 Route 01 Name." } }, //** Define the Next Hop Type of the the Second Route of the Second Route Table */ "RT02Route02NextHopType": { "type": "string", "allowedValues": [ "VirtualNetworkGateway", "VnetLocal", "Internet", "VirtualAppliance", "None" ], "defaultValue": "VirtualAppliance", "metadata": { "description": "Route 02 Next Hop Type." } }, //** Define the address prefix of the the Second Route of the Second Route Table */ "RT02Route02AddressPrefix": { "type": "string", "defaultValue": "10.0.0.32/27", "metadata": { "description": "Route Table 02 Route 01 Address Prefix." } }, //** Define the next hop IP address (the virtual appliance's address) of the the Second Route of the Second Route Table */ "RT02Route02NextHopIPAddress": { "type": "string", "defaultValue": "10.0.0.40", "metadata": { "description": "Next Hop IP Addess." } } }, //** I dont use any variables, you can exclude this section*/ "variables": {}, "resources": [ //* create the First Route Table & Route*/ { "apiVersion": "2017-10-01", "type": "Microsoft.Network/routeTables", "name": "[parameters('RouteTable01Name')]", "location": "[resourceGroup().location]", "properties": { "disableBgpRoutePropagation": true, "routes": [ { "name": "[parameters('Route01Name')]", "properties": { "addressPrefix": "[parameters('Route01AddressPrefix')]", "nextHopType": "[parameters('Route01NextHopType')]", "nextHopIpAddress": "[parameters('RT01Route01NextHopIPAddress')]" } } ] } }, //* create the Second Route Table & Routes*/ { "apiVersion": "2017-10-01", "type": "Microsoft.Network/routeTables", "name": "[parameters('RouteTable02Name')]", "location": "[resourceGroup().location]", "properties": { "disableBgpRoutePropagation": true, "routes": [ { "name": "[parameters('RT02Route01Name')]", "properties": { "addressPrefix": "[parameters('RT02Route01AddressPrefix')]", "nextHopType": "[parameters('RT02Route01NextHopType')]" } }, { "name": "[parameters('RT02Route02Name')]", "properties": { "addressPrefix": "[parameters('RT02Route02AddressPrefix')]", "nextHopType": "[parameters('RT02Route02NextHopType')]", "nextHopIpAddress": "[parameters('RT02Route02NextHopIPAddress')]" } } ] } }, //* create teh Network Security Group */ { "apiVersion": "2019-02-01", "type": "Microsoft.Network/networkSecurityGroups", "name": "[parameters('networkSecurityGroup01Name')]", "location": "[resourceGroup().location]", "properties": { "securityRules": [ { "name": "HTTPS", "properties": { "description": "Open HTTPS to Public", "protocol": "Tcp", "sourcePortRange": "443", "destinationPortRange": "443", "sourceAddressPrefix": "*", "destinationAddressPrefix": "*", "access": "Allow", "priority": 101, "direction": "Inbound" } } ] } }, //* create the Virtual Network */ { "apiVersion": "2018-10-01", "type": "Microsoft.Network/virtualNetworks", "name": "[parameters('vnetName')]", "location": "[resourceGroup().location]", //*add a dependency in order to ensure that the NSG is created before the VNET, in order to be able to attach it*/ "dependsOn": [ "[parameters('networkSecurityGroup01Name')]" ], "properties": { "AddressSpace": { "AddressPrefixes": [ "[parameters('vnetAddressPrefix')]" ] } }, "resources": [ //* create the first subnet */ { "apiVersion": "2018-10-01", "type": "subnets", "location": "[resourceGroup().location]", "name": "[parameters('subnet1Name')]", //* add dependencies to create the resources with an order, because you need to ensure that the VNET is ready before creating the Subnet and also the Route Table*/ "dependsOn": [ "[parameters('vnetName')]", "[resourceId('Microsoft.Network/routeTables', parameters('RouteTable01Name'))]" ], "properties": { "AddressPrefix": "[parameters('subnet1Prefix')]", //*attach the Newtork Securoty Group to the Subnet*/ "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroup01Name'))]"}, //*attacht the First route table to the Subnet*/ "routeTable": { "id": "[resourceId('Microsoft.Network/routeTables', parameters('RouteTable01Name'))]" } } }, //*create the second subnet*/ { "apiVersion": "2018-10-01", "type": "subnets", "location": "[resourceGroup().location]", "name": "[parameters('subnet2Name')]", "dependsOn": [ "[parameters('vnetName')]", "[parameters('subnet1Name')]", "[parameters('RouteTable02Name')]" ], "properties": { "AddressPrefix": "[parameters('subnet2Prefix')]", //*attach the Newtork Securoty Group to the Subnet*/ "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroup01Name'))]"}, //*attacht the second route table to the Subnet*/ "routeTable": { "id": "[resourceId('Microsoft.Network/routeTables', parameters('RouteTable02Name'))]" } } } ] } ] }

Deploy the template

Deploy the template directly from here:

More Azure Resource Manager Templates: https://www.e-apostolidis.gr/microsoft/azure/create-azure-file-shares-using-arm-template-powershell/