Azure Virtual Network Naming Conventions: VNet, Subnet, and NSG
CAF compliant naming for Azure Virtual Networks, subnets, Network Security Groups, and related networking resources, with Terraform and Bicep examples.
Use the CAF prefixes
vnetfor Virtual Networks,snetfor subnets, andnsgfor Network Security Groups, for examplevnet-payments-prod-eus-001andsnet-app-prod-eus-001. They allow alphanumerics, hyphens, underscores, and periods, and must start with a letter or number.
Networking resources in Azure form the backbone of every workload, and they multiply quickly. A single workload might have a VNet, three subnets, two NSGs, a route table, a NAT gateway, and several private endpoints. Without a consistent naming scheme, the relationship between these resources becomes opaque the moment someone outside your team looks at the portal.
This guide covers CAF compliant naming for Azure networking resources, with patterns for VNets, subnets, NSGs, and everything that connects them.
Virtual Network (VNet)
| Attribute | Value |
|---|---|
| CAF prefix | vnet |
| Max length | 64 characters |
| Allowed characters | Alphanumerics, hyphens, underscores, periods |
| Scope of uniqueness | Resource group |
Standard pattern:
vnet-{workload}-{environment}-{region}-{instance}
Examples:
| Workload | Environment | Region | VNet name |
|---|---|---|---|
| Payments | Production | East US | vnet-payments-prod-eus-001 |
| HR portal | Development | West Europe | vnet-hrportal-dev-weu-001 |
| Hub network | Production | East US | vnet-hub-prod-eus-001 |
| Shared services | Production | East US | vnet-shared-prod-eus-001 |
Subnets
Subnets live inside a VNet and don’t need the environment or region in their name (they inherit that context from the VNet). Instead, name subnets by their function:
| Attribute | Value |
|---|---|
| CAF prefix | snet |
| Max length | 80 characters |
| Allowed characters | Alphanumerics, hyphens, underscores, periods |
Pattern:
snet-{function}-{instance}
Examples:
| Function | Subnet name |
|---|---|
| Application tier | snet-app-001 |
| Data tier | snet-data-001 |
| Web / DMZ tier | snet-web-001 |
| Management / bastion | snet-mgmt-001 |
| Private endpoints | snet-pe-001 |
| Azure Kubernetes Service | snet-aks-001 |
| Application Gateway | snet-agw-001 |
Note: Azure reserves several subnet names for specific services, GatewaySubnet, AzureBastionSubnet, AzureFirewallSubnet. Use those exact names for those services; don’t add a prefix.
Network Security Groups
NSGs should be named after what they protect, the subnet or network interface they’re associated with:
| Attribute | Value |
|---|---|
| CAF prefix | nsg |
| Max length | 80 characters |
| Allowed characters | Alphanumerics, hyphens, underscores, periods |
Pattern (subnet-level NSG):
nsg-{subnet-function}-{environment}-{instance}
Examples:
| Association | NSG name |
|---|---|
| App subnet, production | nsg-app-prod-001 |
| Data subnet, production | nsg-data-prod-001 |
| Web subnet, staging | nsg-web-stg-001 |
| AKS subnet, production | nsg-aks-prod-001 |
Route Tables (User Defined Routes)
| Attribute | Value |
|---|---|
| CAF prefix | rt |
| Max length | 80 characters |
Pattern:
rt-{workload}-{environment}-{region}-{instance}
Examples:
rt-payments-prod-eus-001
rt-hub-prod-eus-001
Private Endpoints
Private endpoints connect Azure services to your VNet via a private IP. Name them after both the target service and the service they’re protecting:
| Attribute | Value |
|---|---|
| CAF prefix | pe |
| Max length | 80 characters |
Pattern:
pe-{target-resource-name}-{instance}
Examples:
| Target | Private endpoint name |
|---|---|
Key Vault kv-payments-prod-eus-001 | pe-kv-payments-prod-eus-001 |
Storage stpaymentsprodeus001 | pe-st-payments-prod-eus-001 |
SQL Server sql-payments-prod-eus | pe-sql-payments-prod-eus-001 |
NAT Gateway
| CAF prefix | Max length |
|---|---|
ng | 80 characters |
Pattern:
ng-{workload}-{environment}-{region}-{instance}
Public IP Addresses
Public IPs should describe what they’re attached to:
| Attribute | Value |
|---|---|
| CAF prefix | pip |
| Max length | 80 characters |
Pattern:
pip-{attached-resource}-{environment}-{region}-{instance}
Examples:
pip-agw-payments-prod-eus-001 ← Application Gateway public IP
pip-bastion-prod-eus-001 ← Bastion host public IP
pip-ng-payments-prod-eus-001 ← NAT Gateway public IP
A complete VNet naming example
Here’s what a production networking stack looks like with all names applied:
vnet-payments-prod-eus-001
├── snet-web-001 (web/DMZ tier)
│ └── nsg-web-prod-001
├── snet-app-001 (application tier)
│ └── nsg-app-prod-001
├── snet-data-001 (data tier)
│ └── nsg-data-prod-001
├── snet-pe-001 (private endpoints)
│ ├── pe-kv-payments-prod-eus-001
│ └── pe-st-payments-prod-eus-001
└── snet-agw-001 (Application Gateway)
└── pip-agw-payments-prod-eus-001
The naming makes the topology readable without opening any blade.
Naming in Terraform
variable "workload" { default = "payments" }
variable "environment" { default = "prod" }
variable "region" { default = "eus" }
resource "azurerm_virtual_network" "main" {
name = "vnet-${var.workload}-${var.environment}-${var.region}-001"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
address_space = ["10.0.0.0/16"]
}
resource "azurerm_subnet" "app" {
name = "snet-app-001"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.1.0/24"]
}
resource "azurerm_network_security_group" "app" {
name = "nsg-app-${var.environment}-001"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
}
resource "azurerm_subnet_network_security_group_association" "app" {
subnet_id = azurerm_subnet.app.id
network_security_group_id = azurerm_network_security_group.app.id
}
Naming in Bicep
param workload string = 'payments'
param environment string = 'prod'
param region string = 'eus'
resource vnet 'Microsoft.Network/virtualNetworks@2023-09-01' = {
name: 'vnet-${workload}-${environment}-${region}-001'
location: resourceGroup().location
properties: {
addressSpace: { addressPrefixes: ['10.0.0.0/16'] }
subnets: [
{
name: 'snet-app-001'
properties: { addressPrefix: '10.0.1.0/24' }
}
{
name: 'snet-data-001'
properties: { addressPrefix: '10.0.2.0/24' }
}
]
}
}
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-09-01' = {
name: 'nsg-app-${environment}-001'
location: resourceGroup().location
properties: {}
}
Summary
- VNets:
vnet-{workload}-{environment}-{region}-{instance} - Subnets:
snet-{function}-{instance}, no env/region needed (inherited from VNet) - NSGs:
nsg-{subnet-function}-{environment}-{instance} - Private endpoints:
pe-{target-name}-{instance}, name after what they protect - Reserved subnet names (
GatewaySubnet,AzureBastionSubnet,AzureFirewallSubnet) must be used exactly as-is
Use AzureNamer to generate compliant names for all 200+ Azure resource types including every networking resource above.
Keep reading
Azure API Management Naming Conventions: Service, APIs, and Products
CAF naming for Azure API Management. The service is a globally unique azure-api.net endpoint (1 to 50 chars); APIs, products, backends, and named values inside are function-named. Patterns and examples.
Read →Azure Service Bus Naming Conventions: Namespaces, Queues, and Topics
CAF naming for Azure Service Bus. The namespace is a globally unique servicebus.windows.net endpoint (6 to 50 chars); queues, topics, and subscriptions inside are relaxed. Patterns and examples.
Read →Azure Container Registry Naming: Rules, Limits, and CAF Patterns
Azure Container Registry name requirements: 5 to 50 characters, lowercase alphanumeric only, no hyphens, globally unique. The CAF pattern, examples, and Terraform and Bicep.
Read →Try AzureNamer
Generate CAF compliant names for all 200+ Azure resource types, free, no login required.
Open the Generator →