Azure Network Interfaces
September 6, 2016Azure 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.
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.
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
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.
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.
[…] Azure Network Interfaces […]
Hi Team,
I want to start learning Windows Azure, but please do let me know does Powershell is Mandatory if want to go for Windows AZure.
Please suggest me on this. Your Suggestion Will be highly Appreciated
It’s not required, but it will help. You can do most things through the Azure Interface without PowerShell though.
There are a whole lot of things you can not do on the portal. You will even bump into scenarios where you have certain machine tiers enabled for your subscription but not visible on the UI. You ABSOLUTELY need powershell if you go ARM. But for a developer with near no powershell knowledge the learning curve is no more than a week or two if you have the right training material
First of all great post and great scripts! Second, I traditionally have deployed a VM in Azure then used Powershell to to in and setup static IPs on everything as I didn’t want them to change. I would love to be able to manage my NICs as seperate resources however I don’t need two NICs on each VM. So, do you know if I can create a multi-NIC VM and deploy with your script, attach my newly created NIC object, then turn around and remove the initial NIC that was on the VM at deployment, or should I just disable it and leave it there?
I have never tried that so I can’t give you a definitive answer. I don’t see why that wouldn’t work, but if you try it and find out please post your results in the comments!
Thanks for reading!
Will do, thanks for the reply.
I’m adding a nic after the fact through powershell. I was able to add the subnet for my new nic, the network interface, and I was able to associate it with my vm, but when I try to run the following command as suggested in documntation, it gives me the following error: I can’t find this primary thing anywhere and I checked using a get-azvmnetworkinterface that this server does have a nic assigned to it that is defined as Primary and the new nic I assigned to it is not defined as primary. Any suggestions?
PS C:\WINDOWS\system32> Update-AzVM -ResourceGroupName “P3-HH-Prod-Pool” -VM $VirtualMachine
Update-AzVM : Virtual machine P3-HH-WEB-01 must have one network interface set as the primary.
ErrorCode: VirtualMachineMustHaveOneNetworkInterfaceAsPrimary
ErrorMessage: Virtual machine P3-HH-WEB-01 must have one network interface set as the primary.
ErrorTarget:
StatusCode: 400
ReasonPhrase: Bad Request
OperationID : 7bece00b-4f2d-407d-ae20-b672dc6bb731
At line:1 char:1
+ Update-AzVM -ResourceGroupName “P3-HH-Prod-Pool” -VM $VirtualMachine
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Update-AzVM], ComputeCloudException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.UpdateAzureVMCommand
[…] 9. Azure Network Interfaces – The IT Hollow […]