|

Azure PowerShell Networking Lab: Create a VNet, Add Subnets, and Lock Down Traffic with NSGs

Azure Lab: Secure App-to-Database Networking with VNets, Subnets, Delegation, and NSGs


Scenario

Contoso Coffee Roasters runs a small on-premises office network and is launching a new cloud ordering system in Azure.

They need:

  • A secure private network in Azure for workloads to communicate
  • A dedicated subnet for a managed database service
  • Tight inbound access controls for any admin connectivity
  • Clean structure to expand later without redesigning the network

You will build a VNet, create a subnet, optionally delegate it (for managed database services), and lock it down with an NSG.


Lab Overview

What you will create

  • Resource Group: ContosoRG
  • Virtual Network: ContosoVNet with 10.20.0.0/16
  • Subnet: dbSubnet with 10.20.1.0/24
  • Delegation: Microsoft.Sql/managedInstances (optional but included)
  • NSG: nsg-Contoso-DB attached to dbSubnet
  • Rule: Allow inbound RDP 3389 from your public IP (demo rule)

Note: In production, you should prefer Azure Bastion over public RDP. This lab uses RDP purely to demonstrate NSG rule behavior.


Prerequisites

  • Azure subscription with permissions to create RG, VNet, NSG
  • PowerShell + Az module

0) Pre-Lab Setup

0.1 Install and import Az module

Install-Module Az -Scope CurrentUser -Repository PSGallery -Force
Import-Module Az

0.2 Sign in and set subscription context

Connect-AzAccount
Get-AzSubscription | Select-Object Name, Id
Set-AzContext -Subscription "<SUBSCRIPTION_ID>"

1) Create the Resource Group

$location = "Canada Central"
$rgName   = "ContosoRG"

New-AzResourceGroup -Name $rgName -Location $location

Validate

Get-AzResourceGroup -Name $rgName

2) Create the Virtual Network (VNet)

Contoso uses a private address space sized for growth:

  • /16 gives room for many future subnets (apps, db, management, integration)
$vnetName = "ContosoVNet"
$vnetCidr = "10.20.0.0/16"

New-AzVirtualNetwork `
  -Name $vnetName `
  -ResourceGroupName $rgName `
  -Location $location `
  -AddressPrefix $vnetCidr

Validate

Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName |
  Select-Object Name, Location, @{n="AddressSpace";e={$_.AddressSpace.AddressPrefixes}}

3) Create the Database Subnet

$subnetName = "dbSubnet"
$subnetCidr = "10.20.1.0/24"

$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName

Add-AzVirtualNetworkSubnetConfig `
  -Name $subnetName `
  -VirtualNetwork $vnet `
  -AddressPrefix $subnetCidr

# Commit changes
$vnet | Set-AzVirtualNetwork

Validate

$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$vnet.Subnets | Select-Object Name, AddressPrefix

4) Delegate the Subnet (Managed Database Readiness)

Contoso plans to use Azure SQL Managed Instance, which requires subnet delegation.

$vnet   = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$subnet = Get-AzVirtualNetworkSubnetConfig -Name $subnetName -VirtualNetwork $vnet

Add-AzDelegation `
  -Name "dbDelegation" `
  -ServiceName "Microsoft.Sql/managedInstances" `
  -Subnet $subnet

Set-AzVirtualNetwork -VirtualNetwork $vnet

Validate

$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
($vnet.Subnets | Where-Object Name -eq $subnetName).Delegations |
  Select-Object Name, ServiceName

5) Create an NSG for the Database Subnet

$nsgName = "nsg-Contoso-DB"

$nsg = New-AzNetworkSecurityGroup `
  -Name $nsgName `
  -ResourceGroupName $rgName `
  -Location $location

Validate

Get-AzNetworkSecurityGroup -Name $nsgName -ResourceGroupName $rgName |
  Select-Object Name, Location

6) Attach the NSG to the Subnet

$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$nsg  = Get-AzNetworkSecurityGroup -Name $nsgName -ResourceGroupName $rgName

Set-AzVirtualNetworkSubnetConfig `
  -Name $subnetName `
  -VirtualNetwork $vnet `
  -AddressPrefix $subnetCidr `
  -NetworkSecurityGroup $nsg

Set-AzVirtualNetwork -VirtualNetwork $vnet

Validate

$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
($vnet.Subnets | Where-Object Name -eq $subnetName).NetworkSecurityGroup.Id

Expected: NSG resource ID is returned.


7) Add an Inbound Rule (Demo: Allow RDP from Your IP)

7.1 Get your current public IP

$myIp = (Invoke-RestMethod -Uri "https://api.ipify.org?format=json").ip
$myIp

7.2 Add allow rule

$nsg = Get-AzNetworkSecurityGroup -Name $nsgName -ResourceGroupName $rgName

Add-AzNetworkSecurityRuleConfig `
  -Name "Allow-RDP-Admin" `
  -NetworkSecurityGroup $nsg `
  -Protocol "Tcp" `
  -Direction "Inbound" `
  -Priority 300 `
  -SourceAddressPrefix $myIp `
  -SourcePortRange "*" `
  -DestinationAddressPrefix "*" `
  -DestinationPortRange 3389 `
  -Access "Allow"

Set-AzNetworkSecurityGroup -NetworkSecurityGroup $nsg

Validate

(Get-AzNetworkSecurityGroup -Name $nsgName -ResourceGroupName $rgName).SecurityRules |
  Where-Object Name -eq "Allow-RDP-Admin" |
  Select-Object Name, Priority, Direction, Protocol, SourceAddressPrefix, DestinationPortRange, Access

8) Recommended โ€œReal Worldโ€ Rule Set (Optional Upgrade)

If you want a cleaner, production-like DB subnet posture:

  • Remove public admin rules
  • Allow only traffic from an appSubnet (10.20.2.0/24)
  • Deny everything else inbound

If you want this version, tell me and Iโ€™ll provide the exact rules and priorities.


9) Troubleshooting Checklist

Subnet changes donโ€™t appear

You likely forgot to commit:

Set-AzVirtualNetwork -VirtualNetwork $vnet

Delegation missing

Re-fetch the VNet and re-check delegation after applying updates.

Rule exists but connectivity fails

  • The destination resource must exist and be reachable (VM NIC, public IP, OS firewall)
  • Your public IP may have changed
  • Check effective security rules on the NIC and subnet (Portal: VM NIC โ†’ Effective security rules)

10) Cleanup (Avoid Charges)

Remove-AzResourceGroup -Name $rgName -Force

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *