TTechclick ⚡ XP 0% All lessons
Azure · Network · NSG & Azure FirewallInteractive · L1 / L2 / L3

Azure NSGs vs Azure Firewall: — Layering Network Security the Right Way

An NSG is the gate-pass register at each subnet door; Azure Firewall is the central security checkpoint that decides what may leave the building. Most teams reach for one when they needed both — this lesson shows you exactly where each sits, and how to layer them without breaking routing.

📅 2026-06-11 · ⏱ 13 min · 3 live demos · 4 infographics · 🏷 10-Q assessment + AI Tutor inline

⚡ Quick Answer

Azure NSG vs Azure Firewall for L1/L2 engineers and AZ-500/AZ-700: 5-tuple rules, priority + implicit deny, service tags, ASGs, FQDN filtering, DNAT, forced tunneling and a layered hub-spoke design.

🎯 By the end you will be able to

Read as:

Pick where you want to start

1

The two controls

NSG vs Azure Firewall — and where each one sits.

2

NSG deep-dive

Priority, implicit deny, service tags, ASGs, flow logs.

3

Azure Firewall

FQDN rules, DNAT, threat intel, forced tunneling.

4

Layered design

Hub-spoke, egress lock-down, UDR and routing gotchas.

🧠 Warm-up — 3 questions, no score

Just notice which ones make you pause. We answer all three inside the lesson.

1. A web VM and a database VM sit in the same VNet. You want the web tier blocked from the database's port 1433 unless explicitly allowed. Which control is the natural fit?

Answered in The two controls.

2. You must allow branch servers to reach only *.windowsupdate.com on the internet and block everything else. Which can match on the FQDN?

Answered in Azure Firewall.

3. An NSG has no custom rules. A packet arrives from the internet to your VM on port 8080. What happens?

Answered in NSG deep-dive.

Most engineers think…

Most engineers think "Azure already has NSGs, so I'm covered — an NSG is basically Azure's firewall." So they put a few allow rules on a subnet and call the network secure.

Wrong — and it leaves a gaping hole on the way out. An NSG is a stateful L3–L4 access list on a subnet or NIC: it knows IPs, ports and protocols, and it is free. It has no idea what a domain name is, can't read threat intelligence, and can't inspect the application layer. Azure Firewall is a separate managed service that adds FQDN filtering (allow *.windowsupdate.com, block the rest), threat-intel and IDPS, sitting centrally so all egress is inspected. They are layers, not substitutes — NSG for east-west micro-segmentation, Firewall for north-south egress.

① The two Azure network controls — NSG vs Azure Firewall

Sneha, an L1 cloud engineer at Infosys, gets her first Azure ticket: "the new app VMs can reach each other, but they also reached a sketchy IP overnight — lock it down." She opens the portal and sees two things that both say "security": Network Security Groups and Azure Firewall. Knowing which one answers which question is the whole job here.

Start with the NSG. It is a free, stateful list of allow/deny rules that filters on the 5-tuple, and you attach it to a subnet or a NIC. Rules are priority-ordered (100–4096 for your custom rules, lower number wins), and there are built-in default rules plus service tags so you don't hard-code IPs. What an NSG is great at: deciding who inside the VNet can talk to whom — east-west micro-segmentation.

Now Azure Firewall. It is a separate, billed, managed FWaaS you deploy centrally (usually in a hub VNet). It does everything an NSG can't: FQDN filtering, threat-intelligence filtering, DNAT for inbound, and (on Premium) IDPS. What the Firewall is great at: deciding what is allowed to leave to the internet — north-south egress.

👉 So far: NSG = free, stateful, L3–L4, on a subnet/NIC, for east-west. Firewall = managed, central, FQDN + threat-intel + DNAT, for north-south. Next: see them placed in one design.
Figure 1 — Where each control sits in a hub-spoke
NSG hugs each subnet/NIC for east-west control; Azure Firewall sits central in the hub for north-south egress inspection A hub-and-spoke Azure layout. Two spoke virtual networks each hold a web subnet and a database subnet, with a Network Security Group attached at each subnet controlling east-west traffic between tiers. A central hub virtual network holds one Azure Firewall. A user-defined route of 0.0.0.0/0 points all outbound traffic from the spokes to the firewall's private IP, so internet-bound egress is inspected centrally. Red marks untrusted internet, blue marks trusted inspected paths, amber marks the policy decision point at the firewall, green marks allowed flows. Two controls, two jobs — NSG at the edge of each subnet, Firewall in the centre Spoke VNet — App (10.1.0.0/16) web subnet10.1.1.0/24 db subnet10.1.2.0/24 NSG-web (5-tuple) NSG-db (deny 1433 from web? ) east-west: NSG decides tier-to-tier Hub VNet (10.0.0.0/16) Azure FirewallAzureFirewallSubnetprivate IP 10.0.1.4 FQDN + threat-intel + DNAT + IDPS UDR 0.0.0.0/0 → Firewall (forced via hub) Internetuntrusted — egress must be inspected north-south egress → only via Firewall untrusted / internettrusted / inspectedpolicy / decisionkey insightallowed
Look at the placement: an NSG hugs each subnet (east-west, the small amber chips), while the single Azure Firewall sits in the hub and a UDR 0.0.0.0/0 forces all internet-bound egress through it.

Four facts that separate the two

Tap each card — these are the lines that decide which control you pick in an interview and on the job.

🚪
NSG = subnet/NIC gate
tap to flip

Stateful L3–L4 allow/deny attached to a subnet or NIC. So: it controls who-talks-to-whom inside, and it's free.

🏛️
Firewall = central checkpoint
tap to flip

Managed FWaaS in the hub with FQDN, threat-intel, DNAT, IDPS. So: it controls what leaves to the internet, and it's billed.

🌐
Only Firewall knows names
tap to flip

An NSG can't match *.windowsupdate.com — it only knows IPs/ports. So: domain allow-lists need Azure Firewall.

🧱
They stack, not compete
tap to flip

NSG for east-west, Firewall for north-south, WAF for L7 web attacks. So: a real design uses all three layers.

Daily-life analogy — society gate-pass register vs the main security cabin

Think of a housing society. The NSG is the gate-pass register at each block's door — it checks who (which flat, which floor) may enter that specific block. Fast, local, and it knows nothing beyond "is this visitor on the list for this block." Azure Firewall is the main security cabin at the society's only exit gate — it watches what leaves the campus, can refuse anyone heading to a blacklisted address, and keeps a CCTV log. You need both: the block register stops a courier wandering between flats; the main cabin stops a resident driving off to a banned destination.

Quick check · Q1 of 10

Rahul at TCS must stop the web tier from opening SSH (port 22) to the database tier, both in the same VNet, with no extra cost. What's the right control?

Correct: b. Blocking a specific port between two tiers inside a VNet is textbook east-west micro-segmentation — an NSG (free, stateful, L3–L4) on the database subnet does it cleanly. Routing east-west through a firewall is costly and overkill; a WAF only inspects L7 HTTP, not SSH; threat-intel filtering targets known-bad internet IPs, not internal port control.

Pause & Predict

Predict: an NSG is stateful. If you write ONE inbound allow rule for HTTPS (443) to your web VM, do you also need an outbound rule for the reply traffic — and why? Type your guess.

Answer: No. Because the NSG is stateful, it tracks the connection: once the inbound HTTPS flow is allowed, the return packets are permitted automatically. You only write outbound rules for flows your VM initiates (e.g. the VM reaching out to a patch server), not for replies to inbound connections you already allowed. This is exactly why most NSG rule sets look 'inbound-heavy'.

② NSG deep-dive — priority, the implicit deny, service tags & ASGs

An NSG rule has seven things: priority, direction (Inbound/Outbound), access (Allow/Deny), and the four-plus-protocol match — source, source port, destination, destination port, and protocol (TCP/UDP/ICMP/Any). Priority runs 100–4096 for your custom rules; the lower the number, the higher the priority. The engine walks rules in priority order and stops at the first match — so a Deny at priority 200 beats an Allow at 300.

Every NSG ships with default rules you cannot delete (only override). Inbound: AllowVNetInBound at 65000 (anything inside the VirtualNetwork tag can talk), AllowAzureLoadBalancerInBound at 65001, and DenyAllInBound at 65500. That last one is the implicit deny: if nothing you wrote matched, the packet is dropped. So an NSG with zero custom rules still blocks all inbound internet traffic — but happily allows all traffic within the VNet, which is the part beginners forget.

Figure 2 — How an NSG evaluates a packet
An NSG checks a packet against rules lowest-priority-number first and stops at the first match; if nothing matches before 65500, the implicit DenyAll drops it A packet enters and is evaluated by an NSG. The engine walks rules in priority order from low numbers to high. It first checks the custom Allow-HTTPS rule at priority 100; if the 5-tuple matches, traffic is allowed and processing stops. Otherwise it falls through to the default rules: AllowVNetInBound at 65000, AllowAzureLoadBalancerInBound at 65001, and finally DenyAllInBound at 65500 which silently drops anything unmatched. Amber marks the decision points, green marks an allowed exit, red marks the implicit deny drop. NSG evaluation — lowest priority number wins, first match stops the search packet arrivessrc · dst · port · proto · dir Pri 100 · Allow-HTTPS (custom)src Internet → dst 10.1.1.0/24 : 443 TCP → Allow match → ALLOWstop · stateful return auto match no match ↓ fall through to next priority Pri 65000 · AllowVNetInBound (default)VirtualNetwork → VirtualNetwork : Allow Pri 65001 · AllowAzureLoadBalancerInBoundAzureLoadBalancer (168.63.129.16) → Allow Pri 65500 · DenyAllInBound (implicit)anything unmatched → silently dropped no match → DROPtimeout, not a reset Key insight: NSG is stateful — allow the inbound, the reply is auto-allowed. You almost never write the return rule. untrusted / denytrusted / inspectedpolicy / decisionkey insightallowed
Follow the fall-through: custom Pri-100 first; if it matches, ALLOW and stop. Otherwise drop through the 65000/65001/65500 defaults — and 65500 silently drops anything left.

Two features stop you from drowning in IP addresses. Service tags let you write Source: Internet or Destination: AzureLoadBalancer instead of memorising ranges Microsoft changes weekly — the well-known AzureLoadBalancer tag, for example, maps to the health-probe address 168.63.129.16. Application Security Groups (ASGs) go further: tag each VM's NIC with a role like asg-web or asg-db, then write the rule between roles — "allow asg-webasg-db on 1433" — and any VM you later drop into asg-web inherits the policy with zero IP edits.

🖥️ This is the screen you'll use to add an inbound rule — Azure Portal → Network security groups → (your NSG) → Settings → Inbound security rules → + Add. (Recreated for clarity — your console matches this.)
portal.azure.com · Network security group · Inbound security rules · Add
1
Source
Service Tag
2
Source service tag
Internet
Source port ranges
*
3
Destination
Application security group
Dest. ASG
asg-web
Service / Dest port
HTTPS · 443
Protocol
TCP
4
Action
Allow
5
Priority
100
Name
Allow-HTTPS-Inbound
Add
Azure CLI — create the same inbound rule, then read the effective rules on a NIC
az network nsg rule create \
  --resource-group rg-app-prod --nsg-name nsg-web \
  --name Allow-HTTPS-Inbound --priority 100 \
  --direction Inbound --access Allow --protocol Tcp \
  --source-address-prefixes Internet \
  --destination-asgs asg-web \
  --destination-port-ranges 443

# now prove what the NIC actually sees (custom + defaults merged)
az network nic list-effective-nsg \
  --resource-group rg-app-prod --name nic-web-01 --output table
Expected output
Name                          Priority  Direction  Access  Protocol  DestinationPortRange
Allow-HTTPS-Inbound           100       Inbound    Allow   TCP       443
AllowVnetInBound              65000     Inbound    Allow   *         0-65535
AllowAzureLoadBalancerInBound 65001     Inbound    Allow   *         0-65535
DenyAllInBound                65500     Inbound    Deny    *         0-65535
Common mistake — "my health probes broke after I locked down inbound"

Symptom: you add a tight DenyAllInBound override at priority 200 to stop internet traffic, and suddenly your load balancer marks every backend unhealthy and stops sending traffic. Cause: your deny is higher-priority than the default AllowAzureLoadBalancerInBound (65001), so you accidentally blocked the probe from 168.63.129.16. Fix: add an explicit higher-priority Allow from the AzureLoadBalancer service tag (e.g. priority 150) above your deny — never assume the 65001 default survives your own broad deny.

When something is mysteriously blocked, two tools end the guesswork. Effective security rules (Portal: the NIC's Network settings → Effective security rules, or az network nic list-effective-nsg) show the merged set of subnet-NSG plus NIC-NSG rules actually applied — because a packet must pass both the subnet NSG and the NIC NSG. And flow logs tell you which rule allowed or denied a given flow — though note the NSG flow log story is changing (see the callout below).

2025–2026 change you must know — NSG flow logs are retiring

Microsoft stopped letting you create new NSG flow logs after 30 June 2025, and the feature fully retires on 30 September 2027. The replacement is VNet flow logs, which log at the VNet/subnet/NIC scope with no dependency on an NSG — broader visibility across all workloads, not just NSG-governed traffic. If an exam question or a runbook still says "enable NSG flow logs," flag it: the current answer is migrate to virtual network flow logs via Network Watcher.

Quick check · Q2 of 10

Priya at ICICI tags 6 web VMs into asg-web and 4 DB VMs into asg-db, then writes "allow asg-web → asg-db on 1433." Next month she adds a 7th web VM into asg-web. What must she change in the NSG?

Correct: d. That's the entire point of ASGs: rules reference the group, not IPs, so any NIC added to asg-web inherits the policy with zero rule edits. Adding the IP defeats the purpose; a new NSG fragments policy; and priority below 100 isn't even valid for custom rules (range is 100–4096).

Pause & Predict

Predict: a subnet NSG ALLOWS port 3389, but the NIC NSG on the VM DENIES port 3389. Does RDP reach the VM, and why? Type your guess.

Answer: No. A packet must pass BOTH the subnet NSG and the NIC NSG — they are evaluated as a stack, not 'either-or'. The subnet allows it, but the NIC's deny stops it at the VM. This is exactly what 'effective security rules' is for: it shows the merged result so you can see the NIC's deny winning even though the subnet looked open.

③ Azure Firewall — when NSGs are not enough

An NSG can say "allow 443 to the internet," but it cannot say "allow 443 only to *.windowsupdate.com." The moment you need to control egress by name, by a threat feed, or with deep inspection, you've outgrown the NSG and you reach for Azure Firewall. It has four rule types, and they are processed in a fixed order that trips up a lot of engineers.

The order: threat-intelligence filtering runs first (it can deny a known-bad IP/FQDN before any rule), then DNAT rules, then Network rules, then Application rules. Critically, if a Network rule matches, Application rules are never evaluated — so a sloppy broad "allow 443 to Internet" network rule will quietly bypass your careful FQDN allow-list.

Figure 3 — Azure Firewall rule-processing order
Azure Firewall always runs threat intel first, then DNAT, then Network rules, then Application rules — and the first matching collection wins A pipeline showing Azure Firewall rule processing order for a packet. Threat-intelligence-based filtering runs first and can deny known-malicious IPs and FQDNs before anything else. Then DNAT rules translate inbound public traffic to private IPs. Then Network rules evaluate layer 3 to 4 by IP, port and protocol. Then Application rules evaluate FQDNs and URLs for HTTP, HTTPS and any TCP/UDP. If a Network rule matches, Application rules are not evaluated. Amber marks each decision stage, green marks the allowed exit, red marks a threat-intel or implicit deny. Azure Firewall pipeline — threat intel → DNAT → Network → Application 1· Threat intelknown-bad IP/FQDNalert or deny first 2· DNAT rulespublic:443 → 10.1.1.5inbound translate 3· Network rulesL3–L4 IP/port/protomatch → stop here 4· Application rulesFQDN / URL (L7)*.windowsupdate.com collections walked in this fixed order — within a type, priority decides Key gotcha: a matching Network rule SKIPS Application rulesput a broad "allow 443 to Internet" network rule and your FQDN allow-list never runs match → ALLOWstateful · logged to Log Analytics no match → implicit DENYdefault action = deny, all logged deny / threattrusted flowpolicy / decisionkey insightallowed
Read the pipeline left to right: threat-intel → DNAT → Network → Application. The amber 'key gotcha' band is the one that burns people — a matching Network rule skips the Application rules entirely.

▶ Watch one egress request hit the firewall pipeline

A patch agent on a spoke VM tries to reach windowsupdate.com. Follow the packet through the firewall's rule pipeline, stage by stage. Press Play for the healthy path, then Break it to see the failure.

① Forced via UDR10.1.1.5windowsupdate.com; UDR 0.0.0.0/0 sends it to the firewall 10.0.1.4
② Threat intelfirewall checks the dst against the threat feed — not known-bad, so continue
③ Network rulesno Network rule matches this flow (good — we did NOT add a broad allow-443)
④ Application rulesFQDN rule *.windowsupdate.com matches → ALLOW, logged
Press Play to step through the healthy path. Then press Break it.
Azure CLI — create an FQDN egress allow-list in a Firewall Policy
az network firewall policy rule-collection-group collection add-filter-collection \
  --resource-group rg-hub --policy-name fwpol-prod \
  --rule-collection-group-name DefaultApplicationRuleCollectionGroup \
  --name Allow-PatchEgress --collection-priority 200 \
  --action Allow --rule-name allow-winupdate --rule-type ApplicationRule \
  --source-addresses 10.1.0.0/16 \
  --protocols Http=80 Https=443 \
  --target-fqdns '*.windowsupdate.com' '*.update.microsoft.com'
Expected output
{
  "name": "Allow-PatchEgress",
  "priority": 200,
  "ruleCollectionType": "FirewallPolicyFilterRuleCollection",
  "action": { "type": "Allow" },
  "rules": [ { "name": "allow-winupdate",
    "targetFqdns": [ "*.windowsupdate.com", "*.update.microsoft.com" ] } ]
}

Two more pieces complete the picture. DNAT publishes an inbound service: a rule maps firewall-public-IP:443 to a private backend like 10.1.1.5:443, so the internet only ever sees the firewall. And UDRs are how you force traffic through the firewall: a route table on each spoke subnet sends 0.0.0.0/0 to the firewall's private IP as the next hop. Take it one step further and you have forced tunneling — no subnet breaks out to the internet on its own.

Common mistake — "I put the UDR on every subnet, including the gateway, and connectivity died"

Symptom: after attaching a 0.0.0.0/0 → firewall route everywhere, your VPN/ExpressRoute or the firewall's own management plane breaks. Cause: a default route on the GatewaySubnet (or on the AzureFirewallSubnet itself) hijacks platform routes those subnets need. Fix: never put a 0.0.0.0/0 UDR on the GatewaySubnet or AzureFirewallSubnet; apply it only to workload spoke subnets, and let the gateway and firewall use Azure's system routes.

Karthik at HCL faces this

Karthik, an L2 engineer, gets an alert: a spoke VM is beaconing to a freshly-registered domain at 3 a.m. The NSG shows the traffic 'allowed' because it's just outbound 443 to the internet.

Likely cause

The NSG can only see IP/port — outbound 443 to 'Internet' looks identical whether it's a patch server or a command-and-control domain. There is no FQDN allow-list and no central egress inspection, so the VM can reach anything on 443.

Diagnosis

He confirms the spoke has no UDR forcing egress through Azure Firewall, so the NSG (which can't match domains) is the only thing in the path. He needs name-based egress control, not another IP rule.

Azure Portal → Virtual networks → spoke-app → Subnets → web → Route table (none) → then Firewall → Rules → Application rule collection
Fix

Add a UDR 0.0.0.0/0 → firewall private IP on the spoke web subnet, and an Azure Firewall Application rule collection that allows only the approved FQDNs (patch + business SaaS). Everything else hits the implicit deny.

Verify

Re-test: the VM still reaches *.windowsupdate.com, but the beacon to the suspicious domain is now denied and logged in the Firewall's Application rule logs in Log Analytics.

Quick check · Q3 of 10

Meera at Wipro built a Firewall Application rule allowing only *.ubuntu.com, but VMs can still reach any HTTPS site. A teammate also added a Network rule 'Allow TCP 443 to Internet'. Why is the FQDN allow-list being bypassed?

Correct: c. Azure Firewall processes Network rules before Application rules; once the broad 'allow 443 to Internet' Network rule matches, Application rules are never evaluated, so the *.ubuntu.com restriction is bypassed. Application rules do not run first; FQDN filtering doesn't require IDPS; and threat intel only denies known-bad, it doesn't broadly allow.

Pause & Predict

Predict: you want a branch VM to reach ONLY *.windowsupdate.com on the internet. Should you write that as an Azure Firewall Network rule or an Application rule — and why does the choice matter? Type your guess.

Answer: An Application rule. Only Application rules match on FQDN/URL (L7); Network rules match on IP/port (L3–L4) and can't express a domain name. If you tried to do it as a Network rule you'd be stuck listing Microsoft's ever-changing update IP ranges by hand. And remember the order trap: don't also leave a broad 'allow 443 to Internet' Network rule, or it'll match first and skip your Application rule.

④ Designing layered security — NSG + Firewall in a hub-spoke

Now put it together the way a real Azure landing zone does. NSGs do the micro-segmentation inside each spoke (web subnet can reach app, app can reach db on 1433, nothing else east-west). Azure Firewall does the central egress and inspection in the hub, with every spoke's 0.0.0.0/0 UDR pointed at it. Add a WAF on Application Gateway or Front Door in front of any public web app for L7 attacks. Three layers, three jobs — defence in depth, not three copies of the same control.

Figure 4 — NSG vs Azure Firewall vs WAF — the decision card
Pick the control by the question it answers: NSG for L3-L4 subnet allow/deny, Azure Firewall for central FQDN/threat-intel egress, WAF for L7 web-app attacks A three-column decision card comparing NSG, Azure Firewall and Web Application Firewall. NSG is a free, stateful layer 3 to 4 access control on subnet or NIC, ideal for east-west micro-segmentation, with no FQDN or threat intelligence. Azure Firewall is a managed central stateful firewall-as-a-service with FQDN filtering, threat intelligence, DNAT, and IDPS, ideal for north-south egress control. WAF on Application Gateway or Front Door inspects layer 7 HTTP for OWASP attacks like SQL injection and cross-site scripting. Amber marks the decision question at the top of each column. NSG vs Azure Firewall vs WAF — they are layers, not rivals NSG "who can talk to whom inside?" • L3–L4: 5-tuple allow/deny • on subnet or NIC • stateful · priority-ordered • service tags + ASGs • free with the VNet ✗ no FQDN, no threat intel ✗ no app-layer inspection Use for: east-westmicro-segmentation —web tier can't hit db:1433 Azure Firewall "what can leave to the internet?" • managed FWaaS, central • FQDN / app rules • threat intel + IDPS (Prem) • DNAT for inbound • Firewall Policy, hub-spoke ✗ costs ~per-hour + per-GB ✗ overkill for pure L3-L4 Use for: north-southegress allow-list —only *.windowsupdate.com out WAF (App GW / Front Door) "is this web request an attack?" • L7 HTTP/HTTPS only • OWASP CRS managed rules • blocks SQLi, XSS, bots • rate-limit, geo-filter • inbound web protection ✗ not for non-HTTP traffic ✗ not an egress control Use for: app-layerattacks on your site —' OR 1=1 in a login form amber = the question each layer answers — stack all three for defence in depth
Pick the column by the question at the top (amber). NSG answers 'who talks to whom inside?', Firewall answers 'what may leave to the internet?', WAF answers 'is this web request an attack?' — you usually want all three.

Here is the worked move every team eventually does: lock egress down to approved FQDNs. (1) Deploy Azure Firewall in the hub, in its own AzureFirewallSubnet. (2) On each spoke workload subnet, attach a route table with 0.0.0.0/0 → firewall private IP (forced tunneling — but not on the GatewaySubnet/AzureFirewallSubnet). (3) In the Firewall Policy, create an Application rule collection that allows only the FQDNs the business needs (patch, your SaaS, package mirrors) and rely on the implicit deny for everything else. (4) Keep the spoke NSGs doing east-west — they're still your cheapest, fastest tier-to-tier control.

Azure CLI — the egress lock-down, end to end (route + FQDN rule)
# 1) force the spoke's default route through the firewall
az network route-table route create \
  --resource-group rg-app-prod --route-table-name rt-spoke-web \
  --name to-firewall --address-prefix 0.0.0.0/0 \
  --next-hop-type VirtualAppliance --next-hop-ip-address 10.0.1.4

# 2) allow ONLY approved FQDNs; everything else hits the implicit deny
az network firewall policy rule-collection-group collection add-filter-collection \
  --resource-group rg-hub --policy-name fwpol-prod \
  --rule-collection-group-name DefaultApplicationRuleCollectionGroup \
  --name Allow-ApprovedEgress --collection-priority 300 --action Allow \
  --rule-name approved-saas --rule-type ApplicationRule \
  --source-addresses 10.1.0.0/16 --protocols Https=443 \
  --target-fqdns '*.windowsupdate.com' 'login.microsoftonline.com'
Expected output
{
  "name": "to-firewall",
  "addressPrefix": "0.0.0.0/0",
  "nextHopType": "VirtualAppliance",
  "nextHopIpAddress": "10.0.1.4",
  "provisioningState": "Succeeded"
}
# Application rule collection 'Allow-ApprovedEgress' created (priority 300).
Common mistake — asymmetric routing after you add DNAT

Symptom: you publish a web server via Firewall DNAT (public:443 → 10.1.1.5), inbound works, but some replies are silently dropped and connections hang. Cause: asymmetric routing — the request comes in via the firewall, but the backend's reply takes a different path back out (e.g. its own public IP or a peering shortcut) instead of returning through the firewall, which is stateful and drops the unknown return flow. Fix: make routing symmetric — a UDR on the backend subnet that sends the return traffic back through the firewall, and remove any instance-level public IP on the backend so it can't reply directly.

Pause & Predict

Predict: in this hub-spoke design, if you accidentally create a UDR on Spoke-A that routes traffic to Spoke-B's firewall, and Spoke-B routes back to Spoke-A's firewall, what failure do you get? Type your guess.

Answer: A routing loop — packets bounce between the two firewalls (or back and forth between spokes) until the TTL expires, and the flow times out. This is the UDR-loop gotcha: every spoke's 0.0.0.0/0 must point at the SAME hub firewall, and the firewall/gateway subnets must keep Azure's system routes. One mis-scoped UDR is enough to black-hole a subnet.

For your certs, this lesson sits across two blueprints. On AZ-500 (Azure Security Engineer), "Secure networking" expects you to configure NSGs, ASGs, Azure Firewall and its rules, and understand service tags and the implicit deny. On AZ-700 (Azure Network Engineer), "Design and implement network security" covers exactly this NSG-vs-Firewall placement, hub-spoke routing with UDRs, and the asymmetric-routing traps that catch exam-takers. Get this layering right and you've covered a meaty slice of both.

Figure 5 — NSG & Azure Firewall — the cheat-sheet
Azure NSG and Azure Firewall on one card — default rules, 5-tuple, service tags, FQDN filtering, rule order, ports and the first commands you will type A nine-tile cheat sheet. Tiles cover NSG defaults and priorities, the NSG 5-tuple, service tags and ASGs, the implicit deny and statefulness, Azure Firewall rule order, FQDN application rules, DNAT and forced tunneling, the WAF boundary, and the first CLI commands. Each tile is a one-glance reminder. NSG & Azure Firewall — your one-glance card NSG default rules65000 AllowVNetInBound65001 AllowAzureLoadBalancerInBound65500 DenyAllInBound (implicit)custom priority 100–4096, low = wins NSG 5-tuplesource + src-port + dest +dest-port + protocol+ direction (In / Out)stateful → reply auto-allowed Service tags + ASGstags: Internet, VirtualNetwork,AzureLoadBalancer, Storage…ASG = group VMs by role, not IPrule: asg-web → asg-db (no IPs) Firewall rule order1 Threat intel (first, highest)2 DNAT 3 Network 4 Applicationnetwork match SKIPS applicationdefault action = Deny FQDN / app rulesallow *.windowsupdate.comallow *.ubuntu.com, deny restFQDN tags: WindowsUpdate…central egress allow-list DNAT + forced tunnelDNAT: inbound public → privateUDR 0.0.0.0/0 → fw private IPforced tunnel = all egress via fwnever on GatewaySubnet UDR WAF (the third layer)App Gateway / Front Door, L7OWASP CRS: SQLi, XSS, botsinbound web onlyNSG ≠ Firewall ≠ WAF First commandsaz network nsg rule create …az network nic show-effective-nsgaz network firewall policy rule-collection -group collection add-filter-collection Logging in 2026NSG flow logs retire 30 Sep 2027→ migrate to VNet flow logsFirewall: structured logs + Workbook / Log Analytics
Your one-card map of the whole lesson — NSG defaults, the 5-tuple, service tags/ASGs, the firewall rule order, FQDN rules, DNAT + forced tunneling, where WAF fits, the first commands, and the 2026 logging change.
Daily-life analogy — Aadhaar e-KYC allow-list vs a number-plate barrier

An NSG is the apartment's number-plate barrier: it lets a car in if the plate (IP) and lane (port) are on the list — fast, but it has no idea where the car is going. Azure Firewall's FQDN rules are like an Aadhaar e-KYC allow-list: the destination must prove its name (*.windowsupdate.com) before it's allowed, not just its address. That's why egress control needs the Firewall — names change, IPs lie, and an allow-list of trusted destinations by name is what stops a VM phoning home to a fresh malicious domain.

Next: Microsoft Defender for Cloud
Prove you own the layering

Cold, in 30 seconds: an NSG is stateful L3–L4 on a subnet/NIC for east-west, with default rules ending in DenyAll @ 65500; Azure Firewall is central FWaaS for north-south egress with FQDN/threat-intel/DNAT, rule order threat-intel → DNAT → Network → Application (a network match skips application); WAF handles L7 web attacks. Force egress with a UDR 0.0.0.0/0 → firewall on workload subnets only — never the gateway. Say that without notes and you're ready for the next lesson and the AZ-500/AZ-700 networking domains.

Quick check · Q4 of 10

An interviewer asks Arjun: "Give me the single cleanest way to allow your VMs to download OS patches but reach nothing else on the internet." Best answer?

Correct: a. Name-based egress control is the job: route the spoke's 0.0.0.0/0 to the firewall and allow only *.windowsupdate.com-style FQDNs in an Application rule, letting the implicit deny block everything else. An NSG can't match domains (it'd allow ALL of 443); threat-intel only blocks known-bad, not 'everything except patches'; a WAF protects inbound web apps, not VM egress.

🤖 Ask the AI Tutor

Tap any question — instant, scoped to this lesson. No login, no waiting.

Pre-curated from Azure docs + community Q&A, scoped to this lesson. For a live prod issue, paste your export into chat.techclick.in.

📝 Wrap-up assessment — six more

You've answered 4 inline. Six left. 70% (7 of 10) marks the lesson complete on your profile. Tap Submit all answers at the end.

Q5 · Remember

In a default Azure NSG with no custom rules, which rule and priority drops unmatched inbound internet traffic?

Correct: c. DenyAllInBound at 65500 is the implicit deny — the last default rule that drops anything not matched by a higher-priority rule. 65000 and 65001 are allow rules for VNet and load-balancer traffic; with no custom rules there is no priority-100 rule at all.
Q6 · Apply

An Airtel VNet has a web subnet (10.1.1.0/24) and a db subnet (10.1.2.0/24). You must allow the web tier to reach SQL (1433) on the db tier and block all other east-west traffic to db, at no extra cost. What do you configure?

Correct: a. East-west tier control at no cost is exactly an NSG's job: allow TCP 1433 from the web subnet, let the implicit deny block the rest. Routing east-west through a firewall adds cost and latency; a WAF is L7 inbound web only; NSGs have no threat-intel feature.
Q7 · Apply

You need spoke VMs to reach only *.windowsupdate.com outbound and nothing else. Which Azure Firewall construct allows that, and what forces traffic to the firewall?

Correct: b. Only an Application rule matches the FQDN, and a UDR 0.0.0.0/0 → firewall private IP forces the spoke's egress through it. A Network rule can't match a domain; DNAT is for inbound; NSGs can't filter by FQDN even with a tag.
Q8 · Analyze

A team's Azure Firewall Application rule allows only *.contoso.com, yet VMs reach any HTTPS site. The Application rule is correct and the UDR is in place. What is the most likely cause?

Correct: d. Azure Firewall evaluates Network rules before Application rules, and a Network match skips Application rules entirely — so a broad 'allow 443 to Internet' Network rule bypasses the FQDN allow-list. Threat intel only blocks known-bad; the NSG isn't the firewall's egress control here; and FQDN application rules work on Standard, not just Premium.
Q9 · Analyze

After publishing a web server via Azure Firewall DNAT (public:443 → 10.1.1.5), inbound connections hang and some replies are dropped. Routing into the firewall is correct. Most likely root cause?

Correct: c. DNAT brings the request in via the firewall, but if the backend replies out a different path (its own public IP or a peering shortcut), the stateful firewall sees an unknown return flow and drops it — classic asymmetric routing. The fix is a UDR sending replies back through the firewall and removing any instance-level public IP. An NSG block would stop inbound entirely; DNAT priority and threat intel don't cause one-directional hangs.
Q10 · Evaluate

Two designs for a regulated workload: (A) "NSGs everywhere with tight allow rules, no Azure Firewall — NSGs are our firewall." (B) "NSGs for east-west micro-segmentation, Azure Firewall in the hub for FQDN-based egress with forced tunneling, WAF for the public web app." Which is stronger and why?

Correct: d. B is defence in depth: NSGs handle L3–L4 east-west, the Firewall adds FQDN/threat-intel egress control NSGs can't do, and a WAF covers L7 web attacks. Design A leaves egress blind — an NSG can't allow only *.windowsupdate.com, and service tags are IP groupings, not domain names. The two designs do NOT block the same traffic; A can't enforce name-based egress at all.
Lesson complete — saved to your profile.
Almost! You need 70% (7 of 10) — re-read the path that tripped you up and tap "Try again".

🧠 In your own words

Type one line: In one line, why can an NSG never enforce 'allow only *.windowsupdate.com outbound', but Azure Firewall can? Then compare to the expert version.

Expert version: Because an NSG filters only on the 5-tuple (IP, port, protocol) and has no concept of a domain name, whereas Azure Firewall's Application rules operate at L7 and match on the FQDN itself, so it can allow a name and deny everything else.

🗣 Teach a friend

Best way to lock it in — explain it in one line to a teammate. Tap to generate a paste-ready summary.

📖 Glossary

Network Security Group (NSG)
A free, stateful list of allow/deny rules on a subnet or NIC, filtering on the 5-tuple plus direction.
5-tuple
Source, source port, destination, destination port, protocol — the fields an NSG rule matches on (priority 100–4096, lower = higher).
Default rules
Undeletable NSG rules: AllowVNetInBound (65000), AllowAzureLoadBalancerInBound (65001), DenyAllInBound (65500).
Implicit deny
The default DenyAll rule (65500); anything not matched by a higher-priority rule is silently dropped.
Service tag
An Azure-maintained group of IP ranges (Internet, VirtualNetwork, AzureLoadBalancer, Storage…) you use instead of raw IPs.
Application Security Group (ASG)
A label on VM NICs (asg-web, asg-db) so NSG rules reference workload roles, not IP addresses.
Azure Firewall
A managed, central, stateful FWaaS with FQDN filtering, threat intel, DNAT and (Premium) IDPS.
FQDN / Application rule
An Azure Firewall L7 rule that allows/denies by domain name (e.g. *.windowsupdate.com), unlike an NSG.
DNAT
Destination NAT — translate an inbound firewall public IP:port to a private backend so the internet only sees the firewall.
UDR (User-Defined Route)
A custom route on a subnet, e.g. 0.0.0.0/0 → firewall private IP, overriding Azure's default routing.
Forced tunneling
Routing all internet-bound traffic through the firewall (and optionally on-prem) so no subnet breaks out directly.
Asymmetric routing
When the reply path differs from the request path; a stateful firewall drops the unknown return flow and connections hang.

📚 Sources

  1. Microsoft Learn — "Network security groups overview" (5-tuple rules, priority 100–4096, the three default inbound rules AllowVNetInBound 65000 / AllowAzureLoadBalancerInBound 65001 / DenyAllInBound 65500, stateful behaviour, service tags). learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview
  2. Microsoft Learn — "Application security groups" and "az network nsg rule" CLI reference (group VMs by role; --source-address-prefixes accepts service tags; az network nic list-effective-nsg for the merged effective rules). learn.microsoft.com/en-us/cli/azure/network/nsg/rule
  3. Microsoft Learn — "Azure Firewall rule processing logic" (fixed order: threat-intel first, then DNAT → Network → Application; a Network match skips Application rules) and "Azure Firewall features" (FQDN application rules, DNAT, threat intelligence, IDPS). learn.microsoft.com/en-us/azure/firewall/rule-processing
  4. Microsoft Learn — "Azure Firewall forced tunneling" + Architecture Center hub-spoke guidance (UDR 0.0.0.0/0 → firewall next hop; never a default route on GatewaySubnet; asymmetric-routing caution with DNAT). learn.microsoft.com/en-us/azure/firewall/forced-tunneling · learn.microsoft.com/en-us/azure/firewall/firewall-multi-hub-spoke
  5. Microsoft Learn — "Migrate to virtual network flow logs" (NSG flow logs: no new ones after 30 June 2025, full retirement 30 September 2027; move to VNet flow logs via Network Watcher) and Azure Firewall structured logs (preview/GA, 2025). learn.microsoft.com/en-us/azure/network-watcher/nsg-flow-logs-migrate
  6. Microsoft AZ-500 (Azure Security Engineer) and AZ-700 (Azure Network Engineer) study guides — Secure networking / Design and implement network security: NSGs, ASGs, Azure Firewall rules, service tags, hub-spoke routing. learn.microsoft.com/en-us/credentials/certifications/resources/study-guides/az-500 · learn.microsoft.com/en-us/credentials/certifications/resources/study-guides/az-700

What's next?

You've layered the network controls — but a misconfigured NSG or an exposed port is exactly the kind of thing you want flagged automatically. Next we turn on the watchtower that scores your whole subscription and tells you what to fix first.