Skip to content

10.2 Virtual Network Setup

Overview

This section covers the creation of the Virtual Network (VNet), subnet, and Network Security Group (NSG) that form the foundation of the network infrastructure.

Virtual Network (VNet)

Terraform Configuration

resource "azurerm_virtual_network" "example" {
  name                = var.virtual_network_name
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

Key Properties

  • name: Configurable via variable (default: "test-vnet")
  • address_space: ["10.0.0.0/16"] - Provides 65,536 IP addresses
  • location: Inherited from resource group
  • resource_group_name: References the created resource group

Address Space Breakdown

10.0.0.0/16 = 10.0.0.0 - 10.0.255.255
Total IPs: 65,536
Usable for subnets: 65,531 (Azure reserves 5 IPs per subnet)

Subnet Configuration

Terraform Configuration

resource "azurerm_subnet" "example" {
  name                 = var.subnet_name
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]
}

Key Properties

  • name: Configurable via variable (default: "test-subnet")
  • address_prefixes: ["10.0.1.0/24"] - Provides 256 IP addresses
  • virtual_network_name: References the VNet created above

Subnet Address Breakdown

10.0.1.0/24 = 10.0.1.0 - 10.0.1.255
Total IPs: 256
Azure Reserved: 5 (10.0.1.0-10.0.1.3 and 10.0.1.255)
Usable IPs: 251

Azure Reserved IPs: - 10.0.1.0 - Network address - 10.0.1.1 - Default gateway - 10.0.1.2 - Azure DNS - 10.0.1.3 - Azure DNS (secondary) - 10.0.1.255 - Broadcast address

Network Security Group (NSG)

Terraform Configuration

resource "azurerm_network_security_group" "example" {
  name                = var.network_security_group_name
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  security_rule {
    name                       = "web"
    priority                   = 1008
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "80"
    source_address_prefix      = "*"
    destination_address_prefix = "10.0.1.0/24"
  }
}

Security Rule Breakdown

Property Value Description
name "web" Rule identifier
priority 1008 Lower numbers = higher priority (100-4096)
direction "Inbound" Traffic coming into the subnet
access "Allow" Permits matching traffic
protocol "Tcp" TCP protocol only
source_port_range "*" Any source port
destination_port_range "80" HTTP port
source_address_prefix "*" From any IP address
destination_address_prefix "10.0.1.0/24" To subnet IPs only

What This Rule Does

✅ Allows: HTTP traffic (port 80) from anywhere on the internet to VMs in the subnet ❌ Blocks: All other inbound traffic (default deny)

NSG Association

resource "azurerm_subnet_network_security_group_association" "example_association" {
  subnet_id                 = azurerm_subnet.example.id
  network_security_group_id = azurerm_network_security_group.example.id
}

This associates the NSG with the subnet, applying the security rules to all resources in the subnet.

Variables

Virtual Network Variables

variable "virtual_network_name" {
  type        = string
  default     = "test-vnet"
  description = "Name of the Virtual Network."
}

Subnet Variables

variable "subnet_name" {
  type        = string
  default     = "test-subnet"
  description = "Name of the subnet."
}

NSG Variables

variable "network_security_group_name" {
  type        = string
  default     = "test-nsg"
  description = "Name of the Network Security Group."
}

Network Architecture

┌─────────────────────────────────────────────┐
│  Virtual Network: 10.0.0.0/16              │
│                                             │
│  ┌───────────────────────────────────────┐ │
│  │  Subnet: 10.0.1.0/24                  │ │
│  │                                       │ │
│  │  ┌─────────────────────────────────┐ │ │
│  │  │  Network Security Group         │ │ │
│  │  │  Rule: Allow HTTP (Port 80)     │ │ │
│  │  └─────────────────────────────────┘ │ │
│  │                                       │ │
│  │  Resources:                           │ │
│  │  - VM 0 (10.0.1.x)                   │ │
│  │  - VM 1 (10.0.1.y)                   │ │
│  └───────────────────────────────────────┘ │
└─────────────────────────────────────────────┘

Security Considerations

Current Configuration

  • ✅ Allows HTTP traffic (port 80)
  • ❌ No HTTPS (port 443) - add if needed
  • ❌ No SSH (port 22) - VMs not directly accessible
  • ❌ No RDP (port 3389) - not needed for Linux VMs

Adding SSH Access (Optional)

To enable SSH for management:

security_rule {
  name                       = "ssh"
  priority                   = 1009
  direction                  = "Inbound"
  access                     = "Allow"
  protocol                   = "Tcp"
  source_port_range          = "*"
  destination_port_range     = "22"
  source_address_prefix      = "YOUR_IP_ADDRESS/32"  # Restrict to your IP
  destination_address_prefix = "10.0.1.0/24"
}
security_rule {
  name                       = "https"
  priority                   = 1010
  direction                  = "Inbound"
  access                     = "Allow"
  protocol                   = "Tcp"
  source_port_range          = "*"
  destination_port_range     = "443"
  source_address_prefix      = "*"
  destination_address_prefix = "10.0.1.0/24"
}

Azure CLI Verification

View VNet Details

az network vnet show \
  --resource-group <resource-group-name> \
  --name test-vnet \
  --output json

List Subnets

az network vnet subnet list \
  --resource-group <resource-group-name> \
  --vnet-name test-vnet \
  --output table

View NSG Rules

az network nsg show \
  --resource-group <resource-group-name> \
  --name test-nsg \
  --output json

az network nsg rule list \
  --resource-group <resource-group-name> \
  --nsg-name test-nsg \
  --output table

Common Customizations

Larger Address Space

address_space = ["10.0.0.0/8"]  # 16,777,216 IPs

Multiple Subnets

# Frontend subnet
resource "azurerm_subnet" "frontend" {
  name                 = "frontend-subnet"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]
}

# Backend subnet
resource "azurerm_subnet" "backend" {
  name                 = "backend-subnet"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.2.0/24"]
}

Best Practices

  1. Plan Address Space: Choose non-overlapping ranges if connecting to other networks
  2. Subnet Sizing: Leave room for growth (don't use entire VNet space)
  3. NSG Rules: Use specific source IPs when possible (principle of least privilege)
  4. Rule Priority: Leave gaps (1000, 1010, 1020) for future rules
  5. Documentation: Tag resources with purpose and owner

Next Steps

Proceed to 10.3-Network-Interfaces.md to configure the network interfaces for the VMs.