10.3 Network Interfaces¶
Overview¶
Network Interfaces (NICs) connect virtual machines to the virtual network. This configuration creates two NICs, one for each VM, and associates them with the load balancer's backend pool.
Public IP Address¶
Terraform Configuration¶
resource "azurerm_public_ip" "example" {
name = var.public_ip_name
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
allocation_method = "Static"
sku = "Standard"
}
Key Properties¶
- name: Configurable via variable (default: "test-public-ip")
- allocation_method:
"Static"- IP address doesn't change - sku:
"Standard"- Required for Standard Load Balancer
Static vs Dynamic IP¶
| Type | Use Case | Behavior |
|---|---|---|
| Static | Production, Load Balancers | IP never changes, even when stopped |
| Dynamic | Development, Testing | IP may change when VM is deallocated |
Why Static?: The load balancer needs a consistent public IP address for DNS and client connections.
Network Interface Creation¶
Terraform Configuration¶
resource "azurerm_network_interface" "example" {
count = 2
name = "${var.network_interface_name}${count.index}"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_configuration {
name = "ipconfig${count.index}"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
primary = true
}
}
Understanding the Count Parameter¶
This creates two identical NICs with indices 0 and 1:
- test-nic0 (for VM 0)
- test-nic1 (for VM 1)
IP Configuration Breakdown¶
| Property | Value | Description |
|---|---|---|
| name | ipconfig${count.index} |
ipconfig0, ipconfig1 |
| subnet_id | Reference to subnet | Connects to 10.0.1.0/24 |
| private_ip_address_allocation | "Dynamic" | Azure assigns IP from subnet |
| primary | true | This is the primary IP config |
Private IP Assignment¶
With dynamic allocation, Azure automatically assigns IPs from the subnet range:
- NIC 0 might get: 10.0.1.4
- NIC 1 might get: 10.0.1.5
(Remember: 10.0.1.0-10.0.1.3 are reserved by Azure)
Backend Pool Association¶
Terraform Configuration¶
resource "azurerm_network_interface_backend_address_pool_association" "example" {
count = 2
network_interface_id = azurerm_network_interface.example[count.index].id
ip_configuration_name = "ipconfig${count.index}"
backend_address_pool_id = azurerm_lb_backend_address_pool.example.id
}
What This Does¶
This resource connects each NIC to the load balancer's backend pool:
Key Properties¶
- count: Creates 2 associations (one per NIC)
- network_interface_id: References each NIC using array notation
[count.index] - ip_configuration_name: Must match the IP config name in the NIC
- backend_address_pool_id: References the load balancer's backend pool
Variables¶
variable "public_ip_name" {
type = string
default = "test-public-ip"
description = "Name of the Public IP."
}
variable "network_interface_name" {
type = string
default = "test-nic"
description = "Name of the Network Interface."
}
Network Flow¶
Inbound Traffic (Internet → VMs)¶
Internet
↓
Public IP (Static)
↓
Load Balancer
↓
Backend Pool
↓
┌───┴───┐
↓ ↓
NIC 0 NIC 1
↓ ↓
VM 0 VM 1
Outbound Traffic (VMs → Internet)¶
Resource Dependencies¶
azurerm_subnet.example
↓
azurerm_network_interface.example[0]
azurerm_network_interface.example[1]
↓
azurerm_network_interface_backend_address_pool_association.example[0]
azurerm_network_interface_backend_address_pool_association.example[1]
Azure CLI Verification¶
List Network Interfaces¶
Show NIC Details¶
View IP Configuration¶
az network nic ip-config list \
--resource-group <resource-group-name> \
--nic-name test-nic0 \
--output table
Check Public IP¶
az network public-ip show \
--resource-group <resource-group-name> \
--name test-public-ip \
--output json
# Get just the IP address
az network public-ip show \
--resource-group <resource-group-name> \
--name test-public-ip \
--query ipAddress \
--output tsv
Advanced Configurations¶
Static Private IP Addresses¶
If you need specific private IPs:
resource "azurerm_network_interface" "example" {
count = 2
name = "${var.network_interface_name}${count.index}"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_configuration {
name = "ipconfig${count.index}"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Static"
private_ip_address = "10.0.1.${count.index + 10}" # 10.0.1.10, 10.0.1.11
primary = true
}
}
Multiple IP Configurations¶
For multi-homed scenarios:
ip_configuration {
name = "ipconfig-primary"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
primary = true
}
ip_configuration {
name = "ipconfig-secondary"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
primary = false
}
Accelerated Networking¶
For better performance (requires supported VM sizes):
resource "azurerm_network_interface" "example" {
count = 2
name = "${var.network_interface_name}${count.index}"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
enable_accelerated_networking = true # Add this line
ip_configuration {
name = "ipconfig${count.index}"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
primary = true
}
}
Common Issues and Solutions¶
Issue: NIC Already Attached¶
Error: "Network interface is already attached to a virtual machine"
Solution: Detach from VM before modifying or deleting
Issue: Backend Pool Association Fails¶
Error: "Backend address pool not found"
Solution: Ensure load balancer and backend pool are created first. Check dependencies in Terraform.
Issue: IP Address Conflict¶
Error: "IP address is already in use"
Solution: Use dynamic allocation or choose a different static IP
Best Practices¶
- Use Dynamic IPs: Unless you have a specific reason for static private IPs
- Standard SKU: Always use Standard SKU for production load balancers
- Naming Convention: Use consistent naming with indices (nic0, nic1)
- Accelerated Networking: Enable for production workloads with supported VM sizes
- NSG Association: Can be applied at NIC level or subnet level (subnet is simpler)
Security Considerations¶
- NICs inherit NSG rules from the subnet
- Can apply additional NSG directly to NIC for more granular control
- Public IPs should only be on load balancers, not individual VMs
- Use Azure Bastion or VPN for management access instead of public IPs on VMs
Next Steps¶
Proceed to 10.4-Virtual-Machines-Setup.md to configure the virtual machines that will use these network interfaces.