Create load balancer with NAT rules pointing to VMs using PowerShell

Create load balancer with NAT rules pointing to VMs using PowerShell

Q. How do I create a load balancer with NAT rules pointing to VMs using PowerShell with AzureRM?

A. With Azure Resource Manager (ARM), IaaS cloud services are not used which with Azure Service Manager (ASM) provided a Virtual IP that via endpoints could provide connectivity to VMs from the Internet. With the absence of the cloud service and its VIP there are two approaches to connecting to VMs from the Internet:

  1. Give the VM a Public IP address making it directly communicable from the Internet
  2. Create an external load balanced (a load balancer with a public IP address) that uses NAT rules to directly pass traffic to ports on VMs or load balancing rules to distribute traffic between VMs

Remember both of these approaches should only be used when you need connectivity from the Internet. Most normal communications would occur from on-premises to Azure connections such as site-to-site VPN and ExpressRoute.

The first option is very simple to do, simply create a Public IP (PIP) and assign to the network adapter that will be used with the VM. For example:

$pip = New-AzureRmPublicIpAddress -ResourceGroupName $rgname -Name "pip1" `
-Location $loc -AllocationMethod Dynamic -DomainNameLabel $vmname.ToLower()

$nic = New-AzureRmNetworkInterface -Force -Name ('nic' + $vmname) -ResourceGroupName $rgname `
-Location $loc -SubnetId $subnetId -PublicIpAddressId $pip.Id

To use a load balancer there are numerous options and Microsoft has a great walkthrough at and Below is some simple PowerShell that creates a load balancer only for use with NAT rules to forward traffic and therefore does not use a health probe or normal load balancer objects.

$pipLB = New-AzureRmPublicIpAddress -ResourceGroupName $rgname -Name "vipLB" `
-Location $loc -AllocationMethod Dynamic -DomainNameLabel "viplb"
$frontendIP = New-AzureRmLoadBalancerFrontendIpConfig -Name LB-Frontend -PublicIpAddressId $pipLB.Id
$inboundNATRule1= New-AzureRmLoadBalancerInboundNatRuleConfig -Name "RDP1" `
    -FrontendIpConfiguration $frontendIP -Protocol TCP -FrontendPort 3441 -BackendPort 3389
$NRPLB = New-AzureRmLoadBalancer -ResourceGroupName $rgname -Name "NRP-LB" `
    -Location $loc -FrontendIpConfiguration $frontendIP -InboundNatRule $inboundNATRule1

Notice that this load balancer uses a public IP address for its front end IP then has a single NAT Rule that will forward traffic from port 3441 to a backend port of 3389 (RDP). You can add multiple NAT rules just by creating multiple NAT rule objects and including them in the load balancer, e.g. -InboundNatRule $inboundNATRule1,$inboundNatRule2,etc.

To use the NAT rule created when creating the NIC use:

$nic = New-AzureRmNetworkInterface -Force -Name ('nic' + $vmname) -ResourceGroupName $rgname `
    -Location $loc -SubnetId $subnetId -LoadBalancerInboundNatRule $NRPLB.InboundNatRules[0]

Looking at the properties of the NIC will show the NAT rule. For example:

Name                 : nictestvmARM2
ResourceGroupName    : RG-SCUSA
Location             : southcentralus
Id                   : /subscriptions/466c1a5d-e234-1234-91a5-x234234x0f8/resourceGroups/RG-SCUSA/providers/Microsoft.Networ
Etag                 : W/"4f3e04bb-16b6-4330-83de-a0879b9a4784"
ResourceGuid         : f974a6d1-00b3-40ba-952d-b12026e9bace
ProvisioningState    : Succeeded
Tags                 : 
VirtualMachine       : null
IpConfigurations     : [
                           "Name": "ipconfig1",
                           "Etag": "W/\"4f3e04bb-16b6-4330-83de-a0879b9a4784\"",
                           "Id": "/subscriptions/466c1a5d-e234-1234-91a5-x234234x0f8/resourceGroups/RG-SCUSA/providers/Micro
                           "PrivateIpAddress": "",
                           "PrivateIpAllocationMethod": "Dynamic",
                           "Subnet": {
                             "Id": "/subscriptions/466c1a5d-e234-1234-91a5-x234234x0f8/resourceGroups/RG-SCUSA/providers/Mic
                             "IpConfigurations": []
                           "PublicIpAddress": {
                             "Id": "/subscriptions/466c1a5d-e93b-4138-91a5-670daf44b0f8/resourceGroups/RG-SCUSA/providers/Mic
                           "ProvisioningState": "Succeeded",
                           "LoadBalancerBackendAddressPools": [],
                           "LoadBalancerInboundNatRules": [
                               "Name": "RDP1",
                               "Etag": "W/\"a12a241c-cec4-4111-bd9b-a7db113f03e9\"",
                               "Id": "/subscriptions/466c1a5d-e234-1234-91a5-x234234x0f8/resourceGroups/RG-SCUSA/providers/M
                               "FrontendIPConfiguration": {
                                 "Id": "/subscriptions/466c1a5d-e234-1234-91a5-x234234x0f8/resourceGroups/RG-SCUSA/providers
                               "Protocol": "Tcp",
                               "FrontendPort": 3441,
                               "BackendPort": 3389,
                               "IdleTimeoutInMinutes": 4,
                               "EnableFloatingIP": false,
                               "ProvisioningState": "Succeeded"
DnsSettings          : {
                         "DnsServers": [],
                         "AppliedDnsServers": []
EnableIPForwarding   : False
NetworkSecurityGroup : null
Primary              : False

Note in the example above the NIC has both a public IP and a NAT rule meaning the VM can be accessed from the Internet 2 different ways.

Note you can also use JSON templates which is the preferred approach. Microsoft has examples using templates at with a write-up at includes the VM creation, load balancer creation with a PIP and the NAT rule.

Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.