Azure Network Interfaces

Azure Network Interfaces

September 6, 2016 9 By Eric Shanks

Azure allows you to manage network interfaces as an object that can be decoupled from the virtual machine. This is important to note, because when you delete your virtual machine, the Network Interface will still be in the Azure Portal. This NIC and all of it’s settings will still exist for reuse if you wish. This would include keeping the Public IP Address that is associated with it, subnets, and Network Security Groups.

NOTE: At the time of this writing, Microsoft has a pair of Azure portals including the new Azure Resource Manager portal and the Azure Classic portal. Not all abilities are in the new portal yet. This post focuses solely on the new Azure Resource Manager Portal.

Create a Network Interface

Creating a network interface is pretty simple, but using them can be somewhat confusing to a first timer. To setup a NIC, go to Network Interfaces and click the “Add” button. Give the NIC a descriptive but unique name, then select the VNet and subnet that it is associated with. After this, you can select whether or not the IP Address will be assigned dynamically (think DHCP) or Statically set. If you choose static, you’ll need to provide the private IP Address to be used. Lastly, select a security group if you need one, and then you must select both a subscription as well as a location.

AzureNic1

Once you’ve setup the NIC, it will be stored in Azure as an object with its own list of properties. You can drill down into the object to see the IP Addresses security groups and DNS servers that are associated with it.

AzureNic2

 

Deploying a Multi-Nic Virtual Machine

OK, here’s the rub, when you deploy a new virtual machine through the ARM portal, you aren’t allowed to select the Network Interface! Yep, this is true and I sort of expect this to change in the future because we have a great mechanism to build Network Interfaces, but we have no way to attach the NIC to a virtual machine through the portal. I’ll wait for you to work through your disbelief. When you deploy a new virtual machine a new network interface will be added to it automatically. Having a secondary NIC though is something that is desirable, maybe your virtual machine needs a front-end/back-end setup like in a DMZ.

There are several things that you should know before you try to deploy a Multi-Nic virtual machine in Azure.

  • You can’t deploy a multi-nic virtual machine from the Azure Resource Manager Portal. It must be done through the Azure CLI, API or PowerShell
  • Not every virtual machine can size can support multiple NICs. Make sure that the size you choose will support more than one NIC.
  • You must connect every NIC in a virtual machine to the same VNet. The subnets can be different, but the VNet must be the same. No cross VNet virtual machines.
  • If you plan to add a NIC to an existing virtual machine, it must be a multi-nic virtual machine to start with. You are not allowed to add a second virtual NIC to a machine if it started with one NIC. To add a nic to an existing VM you can go from two Nics to three, but not one NIC to two.
  • If you try to add another NIC to an existing virtual machine, it will be rebooted.
  • When you add a dual NIC VM, one NIC must be marked as primary.

OK, so now we need to know how to deploy our virtual machine through PowerShell instead of through the portal, so that we can make it a multi-nic virtual machine. I’ve provided some sample code below that I used in my deployment. I’ve also got the code stored in Github for public usage if you’d like that.

#Azure Account Variables
$subscr = "AZURERM"
$StorageAccountName = "AZURERMSTORAGEACCOUNT"
$StorageResourceGroup = "AZURESTORAGERESOURCEGROUP"

#set Azure Subscriptions and Storage Account Defaults
Get-AzureRmSubscription -SubscriptionName $subscr | Select-AzureRmSubscription -WarningAction SilentlyContinue
$StorageAccount = Get-AzureRmStorageAccount -name $StorageAccountName -ResourceGroupName $StorageResourceGroup | set-azurermstorageaccount -WarningAction SilentlyContinue

##Global Variables
$resourcegroupname = "AZURERESOURCEGROUPNAME"
$location = "AZURERMLOCATION"

## Compute Variables
$VMName = "AZURERMVIRTUALMACHINENAME"
$ComputerName = "AZUREMACHINENAME"
$VMSize = "AZURERMSIZE"
$OSDiskName = $VMName + "OSDisk"

## Network Variables
$Interface1Name = $VMName + "_int1"
$Interface2Name = $VMName + "_int2"
$Subnet1Name = "AZURERMSUBNET1"
$Subnet2Name = "AZURERMSUBNET2"
$VNetName = "AZURERMVNET"


###########################################################
#Do Not Edit Below This Point                             #
###########################################################

## Network Interface Creation
$PIp1 = New-AzureRmPublicIpAddress -Name $Interface1Name -ResourceGroupName $ResourceGroupName -Location $Location -AllocationMethod Dynamic -WarningAction SilentlyContinue
$VNet = Get-AzureRmVirtualNetwork -name $VNetName -ResourceGroupName $resourcegroupname -WarningAction SilentlyContinue
$Interface1 = New-AzureRmNetworkInterface -Name $Interface1Name -ResourceGroupName $ResourceGroupName -Location $Location -SubnetId $VNet.Subnets[0].Id -PublicIpAddressId $PIp1.Id -WarningAction SilentlyContinue
$Interface2 = New-AzureRmNetworkInterface -Name $Interface2Name -ResourceGroupName $ResourceGroupName -Location $Location -SubnetId $VNet.Subnets[0].Id -WarningAction SilentlyContinue

## Create VM Object
$Credential = Get-Credential
$VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize -WarningAction SilentlyContinue
$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -Windows -ComputerName $ComputerName -Credential $Credential -ProvisionVMAgent -EnableAutoUpdate -WarningAction SilentlyContinue
$VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2012-R2-Datacenter -Version "latest" -WarningAction SilentlyContinue
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $Interface1.Id -WarningAction SilentlyContinue
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $Interface2.Id -WarningAction SilentlyContinue
$OSDiskUri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $OSDiskName + ".vhd" 
$VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -Name $OSDiskName -VhdUri $OSDiskUri -CreateOption FromImage -WarningAction SilentlyContinue
$VirtualMachine.NetworkProfile.NetworkInterfaces.Item(0).Primary = $true 

## Create the VM in Azure
New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $Location -VM $VirtualMachine -WarningAction SilentlyContinue

 

Once you’ve deployed your new virtual machine

 

MultiNic1

 

Add Another NIC to an Existing VM

Now that we’ve got a dual NIC virtual machine and our pre-created Network Interface, we can add this nic to our virtual machine. Again, to do this (as of the time of this blog post) you must do this through the Azure CLI, API, or PowerShell module. The code below is what I used to add my nic to the virtual machine, but I’ve also added the code to the Github Repo as well for your use.

#Set Subscription Variables
Add-AzureAccount
$subscr = "AZURERMSUBSCRIPTION"

Get-AzureRmSubscription -SubscriptionName $subscr | Select-AzureRmSubscription

#Set Variables
$VMname = "VMNAME"
$VMRG =  "VIRTUALMACHINERESOURCEGROUP"
$NIC = "VIRTUALNICNAME"
$NicRG = "NICRESOURCEGROUP"

###################################################
#DO NOT edit below this point                     #
###################################################
#Get the VM
$VM = Get-AzureRmVM -Name $VMname -ResourceGroupName $VMRG
#Get the NIC
$NewNIC =  Get-AzureRmNetworkInterface -Name $NIC -ResourceGroupName $NICRG

#Add the NIC to the VM
$VM = Add-AzureRmVMNetworkInterface -VM $VM -Id $NewNIC.Id

#Reconfigure the VM
#NOTE ------- VM WILL BE RESTARTED!!!!!!!!!!!!!!!!!!!!
Update-AzureRmVM -VM $VM -ResourceGroupName $VMRG

The result is that my HollowNic1 has been added to my virtual machine.

MultiNic2

 

Summary

Network Interfaces might be an important part to you deployment strategy but for now, remember that you must take this into account when you first deploy your machines and it must be done through the CLI, API, or PowerShell. For the time being, this can’t be done through the Azure Resource Manager Portal. Happy coding.