Azure Virtual Networks are the foundation of private networking in Azure. They can isolate resources from the public internet, let you control traffic flow with subnets and network security groups, and connect to on-premises networks or other VNets through peering and VPN gateways. Getting network architecture right at the start is critical because changing it later can require readdressing or migrating workloads. Terraform makes it straightforward to define, version, and replicate your network topology.
Azure Vnet also called Azure Virtual Network is a network that provides various network-related services in Azure. It connects groups of resources and isolates them from outside access in azure cloud. In this article let's see how we can set up Azure Virtual Network using Terraform. The operational reality of this foundation is that the virtual network becomes the boundary inside which identity, routing, and security policies are enforced. When a VNet is defined in Terraform, the definition becomes a declarative record that can be checked into source control, reviewed, and reproduced across environments. The impact for teams is that network drift is observable and reversible because the desired state is codified rather than performed through manual portal clicks.
Infrastructure as a Code allows to representation of cloud infrastructure in the form of code. Terraform is Infrastructure as an infrastructure-as-a-service tool that allows the deployment of resources to multiple cloud providers through code. Azure Virtual Network in Microsoft Azure, a Virtual network is an isolated network that protects a group of resources. The convergence of these three concepts means that a single HCL file can describe the isolation boundary, the address space, and the subnet partitioning that later governs how workloads communicate.
Primary Terminologies Mapped to Terraform Constructs
The reference material identifies Terraform, Azure Virtual Network, and IaC as primary components of Azure Vnet related to Terraform.
- Terraform is described as Infrastructure as an infrastructure-as-a-service tool that allows the deployment of resources to multiple cloud providers through code
- Azure Virtual Network is described as an isolated network that protects a group of resources
- IaC allows representation of cloud infrastructure in the form of code
The impact layer for this mapping is that operators no longer need to translate architectural intent into manual portal steps. The contextual layer connects this to the broader Azure networking stack where VNets are the base layer upon which network security groups, route tables, and peering relationships are built. When those later constructs are also defined in Terraform, the entire networking layer becomes composable.
Local Tooling Prerequisites for Terraform Azure Networking
Setup Azure Virtual Network Using Terraform requires explicit local tooling preparation.
Step 1 Set Up Terraform
- Download the Terraform zip from the installation page of the Terraform website
- Extract and paste the terraform folder to the required location and add the path to runnable in environment variables
- For MacOs install the terraform using HomeBrew
Step 2 Set Up Azure CLI
- Download the Azure CLI setup from the official website
- Run the installer and follow the steps to install
- For MacOs install the Azure CLI using below HomeBrew Command
bash
brew update && brew install azure-cli
Step 3 Configure Azure CLI
- Open terminal and run below command
bash
az login
- A browser window will open for login
- Login with your azure credentials. Once it is done you will see output as below
The practical consequence of this sequence is that the Terraform CLI gains authenticated access to Azure through the credentials established by az login. The CLI installation method varies by operating system, and environment variable configuration is required for the binary to be discoverable in the shell. Without this, terraform init and terraform apply cannot execute.
Provider and Version Constraints in HCL
Terraform enables the definition, preview, and deployment of cloud infrastructure. Using Terraform, you create configuration files using HCL syntax. The HCL syntax allows you to specify the cloud provider - such as Azure - and the elements that make up your cloud infrastructure. After you create your configuration files, you create an execution plan that allows you to preview your infrastructure changes before they're deployed.
The reference material shows two provider constraint patterns.
The first pattern for a simple VNet:
hcl
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.0"
}
}
}
The second pattern for Virtual Network Manager scenarios:
hcl
terraform {
required_version = ">=1.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.56.0"
}
random = {
source = "hashicorp/random"
version = "~>3.0"
}
}
}
Provider configuration in both cases follows:
hcl
provider "azurerm" {
features {}
}
The impact of pinning the azurerm provider is reproducibility. The ~>3.0 constraint allows patch updates within the 3.x series, while >= 3.56.0 forces a minimum capability level needed for Virtual Network Manager resources. The random provider is required only when dynamic naming is desired. The contextual layer ties this to Azure API versioning, where newer provider versions expose newer resource schemas.
A comparison of provider declarations can be summarized as:
| Configuration file | required_version | azurerm source | azurerm version | additional providers |
| providers.tf VNet Manager | >=1.0 | hashicorp/azurerm | >= 3.56.0 | random ~>3.0 |
| main.tf simple VNet | not specified | hashicorp/azurerm | ~>3.0 | none |
Resource Group Creation and Naming Strategies
Create a file named providers.tf and insert the following code. Create a file named main.tf and insert the following code.
The Virtual Network Manager sample creates a resource group with randomized naming:
```hcl
resource "randompet" "rgname" {
prefix = var.resourcegroupname_prefix
}
resource "azurermresourcegroup" "rg" {
location = var.resourcegrouplocation
name = randompet.rgname.id
}
```
The impact of random naming is environment isolation. The prefix variable allows organizational naming conventions to propagate without hardcoding names. The contextual layer connects this to Terraform state management, where resource group name changes are destructive operations requiring recreation.
Virtual Network Resource Definition
The sample VNet resource is defined as:
hcl
resource "azurerm_virtual_network" "samplevnet" {
name = "samplevnet"
resource_group_name = "DeepsLab"
location = "eastus"
address_space = [ "10.0.0.0/16"]
subnet {
name = "subnet-A"
address_prefix = "10.0.1.0/24"
}
}
We have specified the location and resource group where virtual network should be created. We have added a subnet with /24 prefix in the virtual network. We have specified name for Virtual network.
The addressspace of 10.0.0.0/16 provides 65,536 addresses. The embedded subnet subnet-A with addressprefix 10.0.1.0/24 consumes 256 addresses within that space. The impact is that the VNet can host multiple subnets while keeping routing predictable. Changing address_space later requires readdressing or migrating workloads, reinforcing the earlier point about early architecture.
The Virtual Network Manager sample creates three virtual networks with count and dynamic naming:
```hcl
resource "random_string" "prefix" {
length = 4
special = false
upper = false
}
resource "randompet" "virtualnetworkname" {
prefix = "vnet-${randomstring.prefix.result}"
}
resource "azurermvirtualnetwork" "vnet" {
count = 3
name = "${randompet.virtualnetworkname.id}-0${count.index}"
resourcegroupname = azurermresourcegroup.rg.name
location = azurermresourcegroup.rg.location
addressspace = ["10.${count.index}.0.0/16"]
}
```
The impact of count = 3 is a mesh of three VNets each in a distinct /16. The address pattern 10.${count.index}.0.0/16 yields 10.0.0.0/16, 10.1.0.0/16, 10.2.0.0/16. This design supports non-overlapping peering.
Add a subnet to each virtual network:
hcl
resource "azurerm_subnet" "subnet_vnet" {
count = 3
name = "default"
virtual_network_name =
The separate azurerm_subnet resource contrasts with the embedded subnet block in the sample VNet. The embedded approach is concise for simple cases, while separate resources enable richer subnet attributes such as service endpoints and delegation.
Execution Plan and Apply Workflow
Step 5 Apply The Terraform Code
- Once the code is ready you can apply it
- First init the terraform by running below command in project folder where main.tf is present
bash
terraform init
- After successful output of terraform apply the changes using below command
bash
terraform apply
- After verifying type "yes" to confirm and apply
- Terraform will start creating network
- You can also verify deployment by visiting Virtual Networks page of Azure
Once you verify the changes, you apply the execution plan to deploy the infrastructure.
The execution plan phase is the preview capability mentioned in the reference. It shows which resources will be created, updated, or destroyed. The impact is risk reduction before any Azure API calls occur. The contextual layer links this to CI/CD pipelines where terraform plan outputs can be reviewed as artifacts.
Azure Virtual Network Manager Mesh Topology
Get started with Azure Virtual Network Manager by using Terraform to provision connectivity for all your virtual networks. In this quickstart, you deploy three virtual networks and use Azure Virtual Network Manager to create a mesh network topology. Then, you verify that the connectivity configuration was applied. You can choose from a deployment with a Subscription scope or a management group scope. Learn more about network manager scopes.
The mesh topology created by Network Manager centralizes connectivity policies across the three VNets created earlier. Terraform enables the definition, preview, and deployment of cloud infrastructure. Using Terraform, you create configuration files using HCL syntax. The HCL syntax allows you to specify the cloud provider - such as Azure - and the elements that make up your cloud infrastructure. After you create your configuration files, you create an execution plan that allows you to preview your infrastructure changes before they're deployed.
The impact for operators is that connectivity rules are no longer scattered across individual VNet peering resources. The contextual layer connects this to governance at scale, where a management group scope can enforce consistent connectivity across multiple subscriptions.
ExpressRoute and VNet Integration via Terraform
In this quickstart, you use Terraform to create an Azure ExpressRoute circuit and its associated infrastructure. The Terraform template creates a complete ExpressRoute setup including a virtual network, ExpressRoute gateway, circuit configuration, and private peering. All resources are deployed with configurable parameters that allow you to customize the deployment for your specific requirements.
Terraform enables the definition, preview, and deployment of cloud infrastructure. Using Terraform, you create configuration files using HCL syntax. The HCL syntax allows you to specify the cloud provider - such as Azure - and the elements that make up your cloud infrastructure. After you create your configuration files, you create an execution plan that allows you to preview your infrastructure changes before they're deployed.
The ExpressRoute template demonstrates that a VNet created by Terraform can be immediately extended with gateway resources and private peering. The impact is hybrid connectivity as code. The contextual layer ties this back to the initial VNet isolation capability: a VNet can be isolated from the public internet while still being reachable from on-premises networks via ExpressRoute.
Configuration Modifiability and Reuse
We have successfully created Azure Virtual Network with the help of terraform in this article. The configuration described can be further modified to make changes to subnets and network in azure. This is how terraform allows reusable and modifiable configuration of infrastructure.
The reusability claim is realized through variables, count meta arguments, and provider version constraints. The impact is that the same HCL can be reused for dev, test, and prod by changing input variables for location, resource group name prefix, and address spaces. The contextual layer connects this to the earlier warning about readdressing costs: Terraform makes changes visible before they happen, allowing teams to model the impact of subnet modifications in a plan before applying them.