The Short Answer
A well-designed Azure VNet is built around three principles:
- Segmentation — separate workloads into dedicated subnets so you can apply distinct security policies to each
- Least privilege — default to deny, explicitly allow only the traffic you need
- Defense in depth — layer NSGs at the subnet level, add NIC-level rules for sensitive VMs, and route internet-bound traffic through Azure Firewall
Most VNet security failures don't come from sophisticated attacks. They come from flat network designs and NSG rules that were never tightened after initial deployment.
VNet Design Fundamentals
A Virtual Network (VNet) in Azure is your private, isolated network boundary in the cloud. Everything that runs inside a VNet is isolated from the internet and from other VNets by default — unless you explicitly open it up.
The most important design decision you'll make is how to segment your VNet into subnets. Get this right early and security policies become easy to apply and maintain. Get it wrong and you'll spend years trying to retrofit controls onto a flat network.
Subnet Segmentation Strategy
The right approach is to create a dedicated subnet for each distinct workload tier or security boundary. A typical 3-tier application in Azure should look like this:
Notice that each subnet has its own NSG, and the traffic rules between subnets are explicit and minimal. The app subnet only accepts traffic from the web subnet on port 8080. The data subnet only accepts traffic from the app subnet on port 1433. Nothing else gets through.
Subnet Sizing
Azure reserves 5 IP addresses per subnet (the first 4 and the last), so a /24 subnet gives you 251 usable addresses. Plan your subnets larger than you think you need — it's painful to resize a subnet that has resources deployed in it.
A practical sizing guide:
- /28 (11 usable) — small dedicated subnets like Azure Bastion (
AzureBastionSubnet) or VPN Gateway (GatewaySubnet) - /26 (59 usable) — small workload subnets with a handful of VMs
- /24 (251 usable) — standard workload subnet, good default for most tiers
- /23 (507 usable) — large workload subnets like AKS node pools
Don't create one giant subnet and put everything in it. A flat /16 with all workloads in the same subnet means a single misconfigured NSG rule can expose everything. Segment first — it's much harder to do after deployment.
NSG Design Best Practices
NSGs are the primary enforcement mechanism inside a VNet. Applied correctly they give you granular east-west and north-south traffic control. Applied carelessly they become a false sense of security with an Allow Any Any rule sitting at priority 100.
Apply NSGs at the Subnet Level First
Always start with subnet-level NSGs. They apply to everything in the subnet and are easier to manage than NIC-level rules spread across individual VMs. Add NIC-level NSGs only when you need to differentiate security policy within a subnet — for example, a jumpbox VM that needs different inbound rules from the other VMs in the same subnet.
The Allow/Deny Rule Pattern
Every NSG should follow this structure — specific allows first, explicit deny-all at the end:
Use Service Tags instead of IP addresses wherever possible. Tags like AzureLoadBalancer, AzureMonitor, and Storage automatically stay current as Microsoft adds new IPs to those services. Hard-coded IPs in NSG rules break silently when Microsoft rotates infrastructure.
Application Security Groups (ASGs)
ASGs let you group VMs by role and write NSG rules that reference the group rather than individual IP addresses. As your environment scales this becomes essential — maintaining rules with explicit IP lists for 50 web VMs is error-prone and fragile.
Instead of:
You write:
When you add a new web VM, you just assign it to the ASG-WebServers group. The NSG rule automatically covers it — no rule changes required.
VNet Peering: The Security Trap Most Teams Fall Into
VNet peering connects two VNets so resources in each can communicate as if they're on the same network. It's fast, cheap, and widely used. It's also one of the most common sources of unintended lateral movement in Azure environments.
The Problem with Peering
When you peer two VNets, all subnets in both VNets can communicate with each other by default — unless NSGs explicitly block the traffic. Most teams set up peering to allow one specific workload to communicate, then forget that they've effectively opened a path between two entire networks.
Peering a production VNet with a dev/test VNet is one of the most common misconfigurations we see. A developer's compromised machine in the dev VNet now has a direct network path to production resources — unless your NSGs are tight enough to stop it.
Peering Security Checklist
- Never peer dev/test to production without Azure Firewall between them to inspect and filter traffic
- Disable gateway transit unless you specifically need peered VNets to use a shared VPN/ExpressRoute gateway
- Audit peering settings — confirm
AllowForwardedTrafficandAllowGatewayTransitare set intentionally, not left at defaults - Apply NSGs on peered subnets that explicitly limit which source VNets and ports are allowed in
Hub-Spoke as the Safer Alternative
For environments with multiple VNets, a hub-spoke topology with Azure Firewall in the hub is far safer than a mesh of direct VNet peerings. All spoke-to-spoke traffic is routed through the firewall, giving you centralized inspection and logging instead of relying on NSGs alone to prevent lateral movement.
Private Endpoints: Eliminating Public Exposure for Azure Services
By default, Azure PaaS services like Storage, SQL Database, and Key Vault are accessible over public internet endpoints. Even with firewall rules restricting access to your VNet's IP ranges, the traffic still traverses the public internet. Private Endpoints change this.
A Private Endpoint creates a private IP address inside your VNet that maps directly to a specific Azure service. Traffic from your VMs to that service never leaves the Microsoft network backbone — it stays entirely private.
When to Use Private Endpoints
- Any PaaS service holding sensitive data — Storage accounts, SQL databases, Key Vault, Cosmos DB
- Any environment with compliance requirements (PCI-DSS, HIPAA) — Private Endpoints are often a requirement, not just best practice
- Any environment where you want to completely eliminate public internet exposure for backend services
Once you create a Private Endpoint for a service, go back and disable public network access on that service entirely. A Private Endpoint with public access still enabled only halves your attack surface — disabling public access removes it completely.
The Most Common VNet Misconfigurations
After auditing dozens of Azure environments, these are the issues we see most consistently:
| Misconfiguration | Risk | Fix |
|---|---|---|
| Flat VNet with one subnet for everything | Blast radius is entire VNet if one workload is compromised | Segment into workload-specific subnets |
| NSG with Allow Any Any at priority 100 | Effectively no network security controls | Rewrite with explicit allows + deny-all at the end |
| Public IPs on backend VMs | Direct internet exposure, bypasses all perimeter controls | Remove public IPs, use Bastion or Azure Firewall DNAT for access |
| Unrestricted VNet peering to dev/test | Lateral movement path from dev to production | Add Azure Firewall between peered VNets or remove the peering |
| PaaS services with public endpoints | Data accessible over internet even with VNet service endpoints | Migrate to Private Endpoints and disable public access |
| No NSG flow logs enabled | Zero visibility into what traffic is actually flowing | Enable NSG flow logs to Log Analytics or Storage |
| Overly broad IP ranges in NSG rules | Allows more traffic than intended | Tighten source/destination ranges to minimum required |
Logging and Visibility
A VNet with perfect NSG rules and no logging is still flying blind. You need visibility into what traffic is actually flowing — both for security monitoring and for debugging when your NSG rules accidentally block something legitimate.
Enable NSG Flow Logs
NSG Flow Logs capture information about IP traffic flowing through your NSGs — source/destination IP, port, protocol, and whether the traffic was allowed or denied. Enable them on every NSG and send logs to a Log Analytics workspace for querying and alerting.
Microsoft Defender for Cloud
Enable Defender for Cloud's Defender for Servers and Defender for DNS plans across your subscriptions. These provide adaptive network hardening recommendations — Defender analyzes your actual traffic patterns and recommends NSG rules that are tighter than your current configuration based on what it observes.
What to remember from this article
- →Segment early — create dedicated subnets per workload tier from the start, not after deployment
- →NSG rule order matters — specific allows at low priority numbers, explicit deny-all at 4000
- →Use ASGs for any environment with more than a handful of VMs — IP-based rules don't scale
- →VNet peering is not inherently secure — NSGs must explicitly control cross-VNet traffic, especially dev-to-prod
- →Private Endpoints + disabled public access is the gold standard for PaaS service security
- →Enable NSG Flow Logs on every NSG — you can't defend what you can't see