Back
Azure VNet Terraform module with purpose-driven subnets

Designing Azure VNets with Purpose-Driven Subnets (using Terraform Module)

Azure VNet Terraform Module – Explained

An Azure VNet Terraform module is the foundation of every scalable Azure network architecture. Yet in many projects, virtual networks are still designed ad-hoc — without clear intent, subnet boundaries, or future workloads in mind.

In this article, I’ll show how to design Azure VNets using a purpose-driven Terraform module, where subnets are first-class architectural decisions rather than an afterthought.

This approach is based on a reusable Terraform module used across FoggyKitchen Azure content.

📐 Design notes

The short video below explains why Azure VNets must be designed as intent-driven contracts, and why ad-hoc subnet layouts become technical debt long before workloads exist.

This design-level discussion complements the hands-on Terraform implementation described below.

The problem with ad-hoc VNet design

A very common pattern looks like this:

  • Create a VNet

  • Add one or two subnets “for now”

  • Deploy AKS, VMs, or PaaS services

  • Add more subnets later when something breaks

This works — until it doesn’t.

Typical consequences:

  • overlapping address spaces

  • subnets that mix unrelated responsibilities

  • painful refactoring when Private Endpoints or private AKS APIs appear

  • networking becoming the bottleneck instead of the foundation

The root cause is simple: the VNet was not designed with intent.

If you’re starting with Azure networking, this approach is completely natural.
In fact, I’ve previously shown how to build an Azure VNet using raw Terraform resources step by step in this article:

👉 Azure Virtual Network (VNet) and Subnets with Terraform — The Foundation of Your Cloud Network

This is why Azure infrastructure with Terraform should be designed as a layered system — not as isolated resources.

👉 See the full Azure infrastructure with Terraform architecture model: Azure Infrastructure with Terraform – Architecture Model

Thinking in intent, not resources

Instead of asking:

“What resources do I need right now?”

we should ask:

“What responsibilities must this network support over time?”

This shift changes everything.

A subnet is no longer:

  • “where something happens”

It becomes:

  • “where a specific category of traffic and responsibility lives”

Examples:

  • public ingress

  • private workloads

  • application services

  • platform components

  • private endpoints

Azure VNet address space as an architectural decision

One practical example of intent-driven design appears even before Terraform modules are applied: choosing the VNet address space.

A poorly chosen address range often forces painful redesign later — especially when new services like Private Endpoints, AKS, or hub-and-spoke networking are introduced.

For this reason, many Azure VNet address space best practices focus on planning for future platform layers.

Typical considerations include:

• leaving enough address space for multiple subnets
• avoiding CIDR ranges that may overlap with VPN or hybrid networks
• reserving dedicated subnets for platform services such as Private Endpoints or container platforms

In the module used in this article, the address space becomes the network contract that later workloads consume.

Terraform then enforces that contract consistently across environments.

A purpose-driven subnet layout

Design context

This example does not focus on creating individual Azure resources.
Instead, it demonstrates how to design Azure networking as a reusable, opinionated Terraform module.

The goal is not to build “a VNet”, but to create a network foundation that:

  • can be reused across environments,
  • scales naturally with platform services like AKS,
  • and enforces architectural intent through subnet design.

This approach mirrors how real-world Azure landing zones evolve — starting simple, but with clear boundaries that support Private Endpoints, PaaS services, and Kubernetes workloads later on.

Key idea:
We validate the network contract before deploying anything on top of it.

👉 See the full Azure infrastructure with Terraform architecture model: Azure Infrastructure with Terraform – Architecture Model

Figure 1: Azure VNet Terraform module with purpose-driven subnets
A modular network layout where each subnet is designed for a specific workload role (public access, private workloads, applications).

Implementing intent as a Terraform payload

Instead of creating subnets with individual azurerm_subnet resources, we express network intent as data.

Example payload:

subnets = {
  public = {
    address_prefixes = ["10.10.0.0/24"]
  }
  private = {
    address_prefixes = ["10.10.1.0/24"]
  }
  apps = {
    address_prefixes = ["10.10.2.0/24"]
  }
}

This payload is then consumed by a reusable Terraform module.

The reusable VNet module

The module itself lives here:

👉 Repository:
https://github.com/foggykitchen/terraform-az-fk-vnet

It is designed to:

  • accept subnet intent as input

  • create subnets dynamically

  • expose subnet IDs for downstream consumers

  • remain stable as workloads evolve

This allows us to separate network design from network usage.

Example: VNet with purpose-driven subnets

The full working example used in this article is:

👉 Example 02 – VNet with subnets:
https://github.com/foggykitchen/terraform-az-fk-vnet/tree/main/examples/02-vnet-with-subnets

This example intentionally deploys no workloads.

That is not a limitation — it is a design choice.

The goal is to validate:

  • address space planning

  • subnet responsibility

  • future extensibility

before AKS, VMs, or PaaS services are introduced.

Why this approach scales

Once the network is defined this way:

  • AKS can consume a dedicated subnet

  • Private Endpoints can live in a separate, controlled subnet

  • security rules remain predictable

  • future services do not force a redesign

The network stays stable.
Only its consumers change.

This is the foundation of scalable Azure architectures.

From fundamentals to real workloads

In future articles, this exact VNet layout will be reused to deploy:

  • Azure Kubernetes Service (AKS)

  • Azure Container Registry with Private Endpoints

  • Private DNS integration

  • fully private traffic flows

The network itself will not change.
Only the workloads layered on top of it will.

Learn the foundations first

If you want to understand why this matters in real AKS deployments, the next logical step is learning AKS networking fundamentals properly.

👉 Azure Kubernetes Service (AKS) with Terraform – Fundamentals
https://foggykitchen.com/aks-terraform-course/

That course focuses on:

  • AKS networking basics

  • VNet and subnet integration

  • building clusters that don’t need redesign later

This article goes beyond the course on purpose —
but the course gives you the necessary foundation to fully appreciate it.

Building an Azure platform with Terraform

A VNet is only the foundation of an Azure platform. Real environments emerge when networking, storage, compute, and traffic layers are composed together.

Typical next steps include:

Network security boundaries
👉 Azure Network Security Groups with Terraform

Private data services
👉 Azure Blob Storage with Private Endpoint

👉 Azure Files with Private Endpoint

Workloads inside private subnets
👉 Azure Virtual Machines with Terraform

Controlled traffic entry points
👉 Azure Load Balancer with Terraform

👉 Azure NAT Gateway with Terraform

Container platforms built on the same network
👉 Azure Kubernetes Service (AKS) with Terraform

Well-designed Terraform modules allow these layers to be composed predictably and repeatedly.

A strong VNet design becomes the contract that everything else builds on.

Final thoughts

Good Azure architectures are not built by adding resources.

They are built by:

  • designing contracts

  • defining intent

  • and letting modules enforce consistency

A VNet designed this way becomes an asset — not a constraint.

azure fundamentals terraform course architecture diagram with vnet subnets private endpoints and compute

From Network Design to Real Azure Architecture

This article introduced the foundation of every Azure platform — the network boundary.
Real systems are built by layering compute, storage, and private connectivity on top of this design — not by skipping it.
This is exactly the architecture path followed in the Azure Fundamentals course.

🔒 Lifetime • ⏱️ Self-paced • 🧪 Real labs

Check also other courses:​

Leave A Reply

Build Real Azure Architecture with Terraform / OpenTofu

Learn how to design, provision, and evolve Azure platforms step by step — starting from networking, through compute and storage, to private connectivity.

No portals. No shortcuts. Just real, production-ready architecture.

🎓 What you’ll learn:
- Virtual Network design and subnet architecture
- Compute patterns (VMs, Load Balancers, scaling)
- Storage layers (Blob, File, Disks)
- Private connectivity (Private Endpoints, DNS, NAT Gateway)

azure fundamentals terraform course architecture diagram with vnet subnets private endpoints and compute

Learn AKS with Terraform/OpenTofu

This hands-on course teaches you how to deploy and manage Azure Kubernetes Service (AKS) using Terraform/OpenTofu — with production-ready networking, node pools, ACR, autoscaling, monitoring, and real automation workflows.

🎓 What you’ll learn:
- AKS networking (Kubenet/CNI/private)
- ACR integration & CI/CD flow
- Node pools, autoscaling, monitoring

azure aks terraform course