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.
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.
Stateful L3–L4 allow/deny attached to a subnet or NIC. So: it controls who-talks-to-whom inside, and it's free.
Managed FWaaS in the hub with FQDN, threat-intel, DNAT, IDPS. So: it controls what leaves to the internet, and it's billed.
An NSG can't match *.windowsupdate.com — it only knows IPs/ports. So: domain allow-lists need Azure Firewall.
NSG for east-west, Firewall for north-south, WAF for L7 web attacks. So: a real design uses all three layers.
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.
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?
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.
② 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.
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-web → asg-db on 1433" — and any VM you later drop into asg-web inherits the policy with zero IP edits.
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
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
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).
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.
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?
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.
③ 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.
▶ 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.
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'
{
"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.
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.
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.
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 collectionAdd 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.
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.
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?
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.
④ 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.
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.
# 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'
{
"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).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.
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.
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.
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.
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?
🤖 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.
🧠 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.
🗣 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
- 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
- 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
- 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
- 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
- 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
- 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.