DEV Community

Cover image for Zero Trust Network Architecture in Azure: Firewalls, Private Link & NSGs
Raphael Gab-Momoh
Raphael Gab-Momoh

Posted on Originally published at raphaelgmomoh.pages.dev

Zero Trust Network Architecture in Azure: Firewalls, Private Link & NSGs

Introduction to Zero Trust Networking

The traditional castle-and-moat security model — where anything inside the corporate network is implicitly trusted — is obsolete. Once an attacker (or a misconfigured workload) is inside a flat network, there is nothing stopping lateral movement between resources.

Zero Trust replaces that assumption with three operating principles:

  • Verify explicitly — authenticate and authorize based on all available signals, not network location.
  • Use least-privilege access — scope access to what a workload actually needs, nothing more.
  • Assume breach — design so that a single compromised resource cannot reach everything else.

A production-ready Azure network design should incorporate:

  • Segmented Hub-and-Spoke topology
  • Forced tunneling through a central firewall
  • Deny-by-default network security groups
  • Private connectivity to PaaS services
  • Private DNS resolution
  • Identity-based access instead of network-based trust
  • Centralized logging and traffic inspection
  • Automated validation of the above

The goal is not to make the network impenetrable — no network is — but to ensure that a single compromised subnet or credential does not automatically expose everything else.

Before the how, the what — three terms this guide leans on:

  • Network Security Group (NSG) — a set of allow/deny rules attached to a subnet or network interface, filtering traffic by source, destination, port, and protocol. Think of it as a basic firewall placed at each network boundary — deny-by-default, then explicitly allow only the traffic a workload actually needs.
  • VNet peering — a connection between two Virtual Networks that lets resources in each reach the other privately, without traffic crossing the public internet. In a Hub-and-Spoke design, spokes peer only with the hub, deliberately — that's what forces all cross-spoke traffic through the hub's central firewall instead of spokes talking to each other directly.
  • Private Link — a way to reach an Azure PaaS service (a database, a storage account) over a private IP address inside your own VNet, instead of the service's normal public endpoint. Without it, "private" data still has to traverse a public endpoint to reach it — Private Link removes that public exposure entirely.

1. Hub-and-Spoke VNet Topology

The foundation of a segmented Azure network is the Hub-and-Spoke topology.

  • Hub VNet hosts centralized security appliances — Azure Firewall, VPN/ExpressRoute gateways, Azure Bastion — and acts as the single point of connectivity to on-premises networks.
  • Spoke VNets host the actual application and data workloads. They peer with the Hub but never peer directly with each other.
                      On-Premises / Internet
                              |
                              v
                    +-------------------+
                    |      Hub VNet      |
                    |    10.0.0.0/16     |
                    |  Azure Firewall    |
                    +----+----------+----+
                         |          |
                 peering |          | peering
                         v          v
            +-------------------+  +-------------------+
            |   Spoke VNet A     |  |   Spoke VNet B     |
            |   10.1.0.0/16      |  |   10.2.0.0/16      |
            |   App Tier         |  |   Data Tier        |
            +-------------------+  +-------------------+
Enter fullscreen mode Exit fullscreen mode

Because spokes never peer with each other, all inter-spoke ("east-west") traffic is forced through the Hub, giving you a single choke point to inspect and filter every flow.

Do not assume peering alone enforces this. VNet peering only establishes reachability — the routing and firewall rules described in the next section are what actually force traffic through the Hub.


2. Forced Tunneling with User Defined Routes

By default, a VM's outbound traffic goes straight to the internet. To force it through the Hub firewall instead, attach a User Defined Route (UDR) to every spoke subnet that sends a default route (0.0.0.0/0) to the firewall's private IP.

Spoke Subnet (10.1.1.0/24)
         |
         v
  Route Table: 0.0.0.0/0 -> Azure Firewall private IP
         |
         v
  Azure Firewall (Hub VNet, AzureFirewallSubnet)
         |
    Application Rules (allowed FQDNs only)
         |
         v
      Internet
Enter fullscreen mode Exit fullscreen mode

This is often called forced tunneling. Without a route table attached to the subnet, workloads bypass the firewall entirely regardless of how well the firewall itself is configured.


3. Centralized Egress via Azure Firewall

Once traffic is forced through the Hub, Azure Firewall becomes the enforcement point for outbound access.

Configure Application Rules to allow outbound HTTPS traffic only to the fully qualified domain names (FQDNs) a workload actually needs — for example api.github.com or mcr.microsoft.com — and let everything else be dropped by the default deny.

Do not treat the firewall as a set-and-forget appliance. FQDN allow-lists need to be reviewed whenever an application takes on a new external dependency, or legitimate traffic will start failing instead of being logged as a security event.

Azure Firewall overview


4. Micro-Segmentation with NSGs and Application Security Groups

Network Security Groups (NSGs) act as virtual firewalls on subnets and network interfaces. A resilient NSG design follows two rules:

  • Deny all by default — the lowest-priority rule should deny all inbound and outbound traffic, so anything not explicitly allowed is blocked.
  • Group by role, not by IP — Application Security Groups (ASGs) let you write rules against roles like Web-ASG or DB-ASG instead of specific IP addresses that change as resources scale.
{
  "name": "Allow-Web-To-DB",
  "properties": {
    "priority": 200,
    "access": "Allow",
    "direction": "Inbound",
    "protocol": "Tcp",
    "sourcePortRange": "*",
    "destinationPortRange": "1433",
    "sourceApplicationSecurityGroups": [{ "id": ".../applicationSecurityGroups/Web-ASG" }],
    "destinationApplicationSecurityGroups": [{ "id": ".../applicationSecurityGroups/DB-ASG" }]
  }
}
Enter fullscreen mode Exit fullscreen mode

The rule above only permits SQL traffic (port 1433) from members of Web-ASG to members of DB-ASG. Everything else hitting the data-tier subnet is caught by the deny-all rule at the bottom of the NSG.


5. Securing PaaS Services with Azure Private Link

By default, Azure PaaS services — Storage Accounts, Azure SQL, Key Vault — are reachable over the public internet, protected only by identity and firewall rules on the service itself. Azure Private Link removes the public attack surface entirely by projecting the service into your VNet with a private IP address.

The configuration flow:

  1. Disable public network access on the PaaS resource (Azure SQL, Key Vault, etc.).
  2. Create a Private Endpoint for that resource inside a dedicated subnet in the data-tier spoke.
  3. Point a Private DNS Zone (for example privatelink.database.windows.net or privatelink.vaultcore.azure.net) at the private IP, so existing connection strings resolve privately without any application code changes.
  4. Workloads in peered spokes can now reach the service without traffic ever leaving the Microsoft backbone.

Do not skip step 3. Disabling public access and creating the Private Endpoint without the matching Private DNS Zone is a common failure mode — the resource is technically private, but clients still try to resolve the public hostname and connections fail.


6. Identity as the Real Perimeter

Network segmentation limits where traffic can go. It does not decide who is allowed to send it. Zero Trust's "verify explicitly" principle means access decisions should be anchored in identity, not network location.

Application
    |
    v
Managed Identity
    |
    v
Microsoft Entra ID
    |
    v
Azure SQL / Key Vault (RBAC-scoped)
Enter fullscreen mode Exit fullscreen mode

Use managed identities for workload-to-PaaS authentication instead of connection strings or shared keys, and scope Microsoft Entra role assignments to the minimum required — a VM being on the "trusted" subnet should never be treated as sufficient authorization on its own.


7. Validate the Architecture, Don't Assume It

A Zero Trust network is only as good as its last verified state. Configuration drift — a route table detached during troubleshooting, a public-access flag re-enabled by a script — silently reopens the perimeter you built.

Automate two checks continuously:

  • DNS resolution — confirm PaaS hostnames still resolve to private (RFC 1918) addresses, not public ones.
  • Port reachability — confirm only the ports permitted by your NSG rules are actually reachable from a given subnet.
Resolve hostname
      |
      v
  Private IP? --- No --> ALERT: public exposure
      |
     Yes
      |
      v
Test allowed ports
      |
      v
  Only expected ports open? --- No --> ALERT: NSG drift
Enter fullscreen mode Exit fullscreen mode

Run this validation after every deployment, not just once at build time — drift happens after go-live, not during it.


8. Observability

A segmented network still needs centralized visibility. Route the following into Azure Monitor / Log Analytics:

Network Logs

  • NSG flow logs (allowed/denied flows per rule)
  • Azure Firewall logs (application, network, and DNS rule hits)
  • Private DNS Zone query logs

Identity Logs

  • Microsoft Entra sign-in logs
  • Managed identity token requests

Infrastructure Metrics

  • Firewall throughput and rule processing latency
  • Private Endpoint connection state

A useful operational summary might look like:

+------------------------------------------------+
|           ZERO TRUST NETWORK HEALTH             |
+------------------------------------------------+
| Firewall Denies/min | NSG Denies/min | Drift    |
|         14          |        3       |  None    |
+------------------------------------------------+
| Private Endpoints    | Public Exposure          |
|    HEALTHY (4/4)     |    None Detected         |
+------------------------------------------------+
Enter fullscreen mode Exit fullscreen mode

9. Recommended Production Architecture

Putting the pieces together:

                         Internet / On-Prem
                                |
                                v
                       +------------------+
                       |    Hub VNet      |
                       |   10.0.0.0/16    |
                       |  Azure Firewall  |
                       +--------+---------+
                                |
                        Forced Tunneling (UDR)
                                |
                 +--------------+--------------+
                 |                             |
                 v                             v
        +-----------------+           +-----------------+
        |  Spoke A: App    |           |  Spoke B: Data   |
        |  10.1.0.0/16     |           |  10.2.0.0/16     |
        |  NSG + ASGs      |           |  Private Endpoints|
        +-----------------+           +--------+----------+
                                                |
                                        Private DNS Zones
                                                |
                                                v
                                     Azure SQL / Key Vault

        Identity     -> Microsoft Entra ID + Managed Identities
        Monitoring   -> Azure Monitor / NSG Flow Logs / Firewall Logs
        Validation   -> Automated DNS + port-reachability checks
        IaC          -> Bicep
Enter fullscreen mode Exit fullscreen mode

Operational Checklist

Before considering a Zero Trust network deployment complete, verify:

  • [ ] Spoke VNets peer only with the Hub, never with each other.
  • [ ] Every spoke subnet has a route table forcing 0.0.0.0/0 to the firewall.
  • [ ] Azure Firewall Application Rules allow only required FQDNs.
  • [ ] Every NSG ends with an explicit deny-all rule.
  • [ ] NSG rules reference Application Security Groups, not hardcoded IPs, where possible.
  • [ ] Public network access is disabled on every PaaS resource that has a Private Endpoint.
  • [ ] Matching Private DNS Zones are linked to every VNet that needs to resolve a private endpoint.
  • [ ] Workload-to-PaaS authentication uses managed identities, not shared keys.
  • [ ] DNS resolution and port-reachability are validated automatically after every deployment.
  • [ ] NSG flow logs and Firewall logs are flowing into Azure Monitor.
  • [ ] IaC (Bicep) is the source of truth — no manual portal changes to routing or NSGs.

Final Takeaway

Zero Trust networking in Azure is not a single toggle switch — it is a layered defense strategy where each layer assumes the others might fail.

Segmentation → forced tunneling → firewall enforcement → micro-segmentation → private connectivity → identity → continuous validation → observability.

The strongest architecture assumes a subnet or credential will eventually be compromised, and is designed so that compromise stays contained.

Zero Trust = Segmentation + Identity + Private Connectivity + Continuous Validation

Zero Trust · Hub-and-Spoke · Azure Firewall · NSG · Private Link · Bicep


Originally published on my portfolio.

Top comments (0)