How to create a Linux virtual machine in Azure with multiple network interface cards

You can create a virtual machine (VM) in Azure that has multiple virtual network interfaces (NICs) attached to it. A common scenario is to have different subnets for front-end and back-end connectivity, or a network dedicated to a monitoring or backup solution. This article details how to create a VM with multiple NICs attached to it and how to add or remove NICs from an existing VM. Different VM sizes support a varying number of NICs, so size your VM accordingly.

This article details how to create a VM with multiple NICs with the Azure CLI 2.0. You can also perform these steps with the Azure CLI 1.0.

Create supporting resources

Install the latest Azure CLI 2.0 and log in to an Azure account using az login.

In the following examples, replace example parameter names with your own values. Example parameter names included myResourceGroup, mystorageaccount, and myVM.

First, create a resource group with az group create. The following example creates a resource group named myResourceGroup in the eastus location:

az group create --name myResourceGroup --location eastus

Create the virtual network with az network vnet create. The following example creates a virtual network named myVnet and subnet named mySubnetFrontEnd:

az network vnet create \
    --resource-group myResourceGroup \
    --name myVnet \
    --address-prefix 192.168.0.0/16 \
    --subnet-name mySubnetFrontEnd \
    --subnet-prefix 192.168.1.0/24

Create a subnet for the back-end traffic with az network vnet subnet create. The following example creates a subnet named mySubnetBackEnd:

az network vnet subnet create \
    --resource-group myResourceGroup \
    --vnet-name myVnet \
    --name mySubnetBackEnd \
    --address-prefix 192.168.2.0/24

Create a network security group with az network nsg create. The following example creates a network security group named myNetworkSecurityGroup:

az network nsg create \
    --resource-group myResourceGroup \
    --name myNetworkSecurityGroup

Create and configure multiple NICs

Create two NICs with az network nic create. The following example creates two NICs, named myNic1 and myNic2, connected the network security group, with one NIC connecting to each subnet:

az network nic create \
    --resource-group myResourceGroup \
    --name myNic1 \
    --vnet-name myVnet \
    --subnet mySubnetFrontEnd \
    --network-security-group myNetworkSecurityGroup
az network nic create \
    --resource-group myResourceGroup \
    --name myNic2 \
    --vnet-name myVnet \
    --subnet mySubnetBackEnd \
    --network-security-group myNetworkSecurityGroup

Create a VM and attach the NICs

When you create the VM, specify the NICs you created with --nics. You also need to take care when you select the VM size. There are limits for the total number of NICs that you can add to a VM. Read more about Linux VM sizes.

Create a VM with az vm create. The following example creates a VM named myVM:

az vm create \
    --resource-group myResourceGroup \
    --name myVM \
    --image UbuntuLTS \
    --size Standard_DS3_v2 \
    --admin-username azureuser \
    --generate-ssh-keys \
    --nics myNic1 myNic2

Add a NIC to a VM

The previous steps created a VM with multiple NICs. You can also add NICs to an existing VM with the Azure CLI 2.0. Different VM sizes support a varying number of NICs, so size your VM accordingly. If needed, you can resize a VM.

Create another NIC with az network nic create. The following example creates a NIC named myNic3 connected to the back-end subnet and network security group created in the previous steps:

az network nic create \
    --resource-group myResourceGroup \
    --name myNic3 \
    --vnet-name myVnet \
    --subnet mySubnetBackEnd \
    --network-security-group myNetworkSecurityGroup

To add a NIC to an existing VM, first deallocate the VM with az vm deallocate. The following example deallocates the VM named myVM:

az vm deallocate --resource-group myResourceGroup --name myVM

Add the NIC with az vm nic add. The following example adds myNic3 to myVM:

az vm nic add \
    --resource-group myResourceGroup \
    --vm-name myVM \
    --nics myNic3

Start the VM with az vm start:

az vm start --resource-group myResourceGroup --name myVM

Remove a NIC from a VM

To remove a NIC from an existing VM, first deallocate the VM with az vm deallocate. The following example deallocates the VM named myVM:

az vm deallocate --resource-group myResourceGroup --name myVM

Remove the NIC with az vm nic remove. The following example removes myNic3 from myVM:

az vm nic remove \
    --resource-group myResourceGroup \
    --vm-name myVM \
    --nics myNic3

Start the VM with az vm start:

az vm start --resource-group myResourceGroup --name myVM

Create multiple NICs using Resource Manager templates

Azure Resource Manager templates use declarative JSON files to define your environment. You can read an overview of Azure Resource Manager. Resource Manager templates provide a way to create multiple instances of a resource during deployment, such as creating multiple NICs. You use copy to specify the number of instances to create:

"copy": {
    "name": "multiplenics"
    "count": "[parameters('count')]"
}

Read more about creating multiple instances using copy.

You can also use a copyIndex() to then append a number to a resource name, which allows you to create myNic1, myNic2, etc. The following shows an example of appending the index value:

"name": "[concat('myNic', copyIndex())]", 

You can read a complete example of creating multiple NICs using Resource Manager templates.

Configure guest OS for multiple NICs

When you add multiple NICs to a Linux VM, you need to create routing rules. These rules allow the VM to send and receive traffic that belongs to a specific NIC. Otherwise, traffic that belongs to eth1, for example, cannot be processed correctly by the defined default route.

To correct this routing issue, first add two routing tables to /etc/iproute2/rt_tables as follows:

echo "200 eth0-rt" >> /etc/iproute2/rt_tables
echo "201 eth1-rt" >> /etc/iproute2/rt_tables

To make the change persistent and applied during network stack activation, edit /etc/sysconfig/network-scipts/ifcfg-eth0 and /etc/sysconfig/network-scipts/ifcfg-eth1. Alter the line "NM_CONTROLLED=yes" to "NM_CONTROLLED=no". Without this step, the additional rules/routing are not automatically applied.

Next, extend the routing tables. Let's assume we have the following setup in place:

Routing

default via 10.0.1.1 dev eth0 proto static metric 100
10.0.1.0/24 dev eth0 proto kernel scope link src 10.0.1.4 metric 100
10.0.1.0/24 dev eth1 proto kernel scope link src 10.0.1.5 metric 101
168.63.129.16 via 10.0.1.1 dev eth0 proto dhcp metric 100
169.254.169.254 via 10.0.1.1 dev eth0 proto dhcp metric 100

Interfaces

lo: inet 127.0.0.1/8 scope host lo
eth0: inet 10.0.1.4/24 brd 10.0.1.255 scope global eth0    
eth1: inet 10.0.1.5/24 brd 10.0.1.255 scope global eth1

You would then create the following files and add the appropriate rules and routes to each:

  • /etc/sysconfig/network-scripts/rule-eth0

    from 10.0.1.4/32 table eth0-rt
    to 10.0.1.4/32 table eth0-rt
    
  • /etc/sysconfig/network-scripts/route-eth0

    10.0.1.0/24 dev eth0 table eth0-rt
    default via 10.0.1.1 dev eth0 table eth0-rt
    
  • /etc/sysconfig/network-scripts/rule-eth1

    from 10.0.1.5/32 table eth1-rt
    to 10.0.1.5/32 table eth1-rt
    
  • /etc/sysconfig/network-scripts/route-eth1

    10.0.1.0/24 dev eth1 table eth1-rt
    default via 10.0.1.1 dev eth1 table eth1-rt
    

To apply the changes, restart the network service as follows:

systemctl restart network

The routing rules are now correctly in place and you can connect with either interface as needed.

Next steps

Review Linux VM sizes when trying to creating a VM with multiple NICs. Pay attention to the maximum number of NICs each VM size supports.