Home DevOps Microsoft Azure — Network Security Groups & ASGs
Intermediate 8 min · July 12, 2026

Microsoft Azure — Network Security Groups & ASGs

NSG rules, application security groups, service tags, and effective security rules..

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Drawn from code that ran under real load.

Follow
Verified
production tested
July 12, 2026
last updated
1,983
articles · all by Naren
Before you start⏱ 25 min
  • Azure subscription with contributor access, Azure CLI 2.50+, basic understanding of Azure networking (VNet, subnet), familiarity with bash or PowerShell, and a test VM or two to apply NSG rules.
✦ Definition~90s read
What is Network Security Groups & ASGs?

Microsoft Azure — Network Security Groups & ASGs is a core Azure service that handles nsg asg in the Microsoft cloud ecosystem.

Network Security Groups & ASGs is like having a specialized tool that handles nsg asg in the Microsoft cloud — you manage the configuration, Azure handles the infrastructure.
Plain-English First

Network Security Groups & ASGs is like having a specialized tool that handles nsg asg in the Microsoft cloud — you manage the configuration, Azure handles the infrastructure.

Azure is Microsoft's cloud computing platform offering over 200 services. This article covers network security groups & asgs with production-ready configurations, best practices, and hands-on examples.

Why Network Security Groups Are Not Optional

Network Security Groups (NSGs) are the first line of defense for any Azure virtual network. They act as a distributed, stateful firewall that filters traffic at the subnet or NIC level. In production, every subnet should have at least one NSG attached. Without NSGs, your VNet is wide open — any VM can reach any other VM, and inbound traffic from the internet is unrestricted by default. I've seen teams skip NSG configuration during rapid prototyping, only to be hit by lateral movement attacks after a breach. NSGs are free, easy to audit, and can prevent entire classes of incidents. The rule of thumb: default deny inbound, default allow outbound, and explicitly permit only what's necessary. This section sets the foundation for understanding how to build secure, scalable network policies.

create-nsg.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
az network nsg create \
  --resource-group prod-rg \
  --name app-nsg \
  --location eastus

az network nsg rule create \
  --resource-group prod-rg \
  --nsg-name app-nsg \
  --name AllowHTTP \
  --priority 100 \
  --direction Inbound \
  --access Allow \
  --protocol Tcp \
  --destination-port-ranges 80 \
  --source-address-prefixes Internet
Output
{
"defaultSecurityRules": [...],
"id": "/subscriptions/.../resourceGroups/prod-rg/providers/Microsoft.Network/networkSecurityGroups/app-nsg",
"location": "eastus",
"name": "app-nsg",
"securityRules": [
{
"access": "Allow",
"destinationPortRanges": ["80"],
"direction": "Inbound",
"name": "AllowHTTP",
"priority": 100,
"protocol": "Tcp",
"sourceAddressPrefixes": ["Internet"],
"sourcePortRange": "*"
}
]
}
⚠ Default Rules Can Bite You
Azure NSGs include default rules that allow all outbound traffic and deny all inbound from the internet. If you accidentally remove the deny rule or misconfigure priorities, you might expose services unintentionally. Always test with a tool like az network nsg rule list before applying to production.
📊 Production Insight
In a past incident, a team attached an NSG to the subnet but not the NIC, leaving a VM exposed via its public IP. Always attach at both levels for defense in depth.
🎯 Key Takeaway
NSGs are free, stateful firewalls that must be attached to every subnet and NIC in production.
azure-nsg-asg THECODEFORGE.IO NSG Rule Evaluation Flow Step-by-step process of how NSG rules are evaluated Inbound/Outbound Packet Packet arrives at network interface Check Priority Order Rules evaluated from lowest to highest priority number Evaluate Rule Conditions Source, destination, port, protocol match Allow or Deny Decision First matching rule determines action Apply Default Rules If no custom rule matches, default deny applies ⚠ Misordered priority can bypass intended restrictions Always place explicit deny rules at highest priority THECODEFORGE.IO
thecodeforge.io
Azure Nsg Asg

NSG Rule Evaluation: Priority, Direction, and Flow

NSG rules are evaluated in priority order, lowest number first. Each rule has a direction (Inbound or Outbound), source/destination address prefixes, port ranges, and protocol. Rules are stateful — if you allow inbound traffic on port 443, the return traffic is automatically allowed regardless of outbound rules. This is a common point of confusion: you don't need a matching outbound rule for responses. However, outbound initiated traffic requires explicit outbound rules. In production, always reserve priority ranges: use 100-199 for critical allow rules, 200-299 for less critical, and 3000+ for deny rules. This prevents accidental overrides when adding new rules. Also, remember that NSG rules are evaluated per packet, not per connection — but statefulness means the first packet creates a flow entry.

list-nsg-rules.shBASH
1
2
3
4
5
az network nsg rule list \
  --resource-group prod-rg \
  --nsg-name app-nsg \
  --query "[].{Name:name, Priority:priority, Direction:direction, Access:access, Source:sourceAddressPrefixes, DestPort:destinationPortRanges}" \
  --output table
Output
Name Priority Direction Access Source DestPort
------------ ---------- ----------- -------- ---------- ----------
AllowHTTP 100 Inbound Allow Internet 80
DenyAllIn 65000 Inbound Deny * *
AllowVNetIn 65001 Inbound Allow VirtualNet *
AllowAzureLB 65002 Inbound Allow AzureLoadB *
DenyAllOut 65000 Outbound Deny * *
AllowVNetOut 65001 Outbound Allow VirtualNet *
AllowInternet 65002 Outbound Allow * *
🔥Statefulness Means No Return Rules Needed
When you allow inbound TCP/443, the outbound response is automatically permitted. Do not create a corresponding outbound allow rule — it's redundant and can clutter your NSG.
📊 Production Insight
I once saw a team add 50 outbound rules to match every inbound rule, thinking it was required. This caused rule exhaustion (max 1000 rules per NSG) and broke connectivity. Trust the stateful firewall.
🎯 Key Takeaway
NSG rules are evaluated by priority; statefulness handles return traffic automatically.

Application Security Groups: Logical Grouping at Scale

Application Security Groups (ASGs) let you group VMs by application role — like 'web', 'app', or 'db' — and reference those groups in NSG rules instead of IP addresses. This decouples security from network topology. When you scale out or replace VMs, you just update the ASG membership; the NSG rules stay the same. In production, ASGs are essential for microservices architectures where IPs change frequently. For example, you can create a rule that allows traffic from the 'web' ASG to the 'app' ASG on port 8080. ASGs are regional and can span VNets if peered. However, they don't support external IPs or service tags — those still need explicit prefixes. Use ASGs for east-west traffic within your VNet.

create-asg.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
az network asg create \
  --resource-group prod-rg \
  --name web-asg \
  --location eastus

az network asg create \
  --resource-group prod-rg \
  --name app-asg \
  --location eastus

az network nic ip-config update \
  --resource-group prod-rg \
  --nic-name web-vm-nic \
  --name ipconfig1 \
  --application-security-groups web-asg

az network nsg rule create \
  --resource-group prod-rg \
  --nsg-name app-nsg \
  --name AllowWebToApp \
  --priority 200 \
  --direction Inbound \
  --access Allow \
  --protocol Tcp \
  --destination-port-ranges 8080 \
  --source-asgs web-asg
Output
{
"name": "AllowWebToApp",
"priority": 200,
"sourceApplicationSecurityGroups": [
{
"id": "/subscriptions/.../resourceGroups/prod-rg/providers/Microsoft.Network/applicationSecurityGroups/web-asg"
}
],
"destinationPortRanges": ["8080"]
}
💡ASGs Reduce Rule Count
Instead of creating a rule per VM IP, use one rule per ASG pair. This keeps your NSG manageable even with hundreds of VMs.
📊 Production Insight
During a migration, we moved VMs to new subnets but kept the same ASGs. The NSG rules still worked because they referenced ASGs, not IPs. Zero firewall changes needed.
🎯 Key Takeaway
ASGs abstract IPs into logical roles, making NSG rules portable and scalable.
azure-nsg-asg THECODEFORGE.IO NSG and ASG Layered Security Defense in depth with network and application security groups Virtual Network Subnet A | Subnet B | Subnet C Network Security Group Inbound Rules | Outbound Rules | Service Tags Application Security Group Web Tier | App Tier | Data Tier Virtual Machines VM1 | VM2 | VM3 THECODEFORGE.IO
thecodeforge.io
Azure Nsg Asg

Combining NSGs and ASGs for Defense in Depth

In production, you should attach NSGs at both subnet and NIC levels, and use ASGs for intra-application rules. The subnet NSG enforces boundary policies (e.g., deny all inbound from internet except to the web tier), while the NIC NSG applies per-role rules (e.g., allow only web tier to app tier). When both are attached, the NIC NSG is evaluated after the subnet NSG. Traffic must pass both to reach the VM. This layered approach prevents misconfigurations in one NSG from exposing the entire subnet. For example, if the subnet NSG accidentally allows all inbound, the NIC NSG can still block it. Use ASGs in the NIC NSG to keep rules clean. Always document which NSG is responsible for what — I've seen teams duplicate rules across both, leading to confusion.

attach-nsg-nic.shBASH
1
2
3
4
5
6
7
8
9
10
az network nic update \
  --resource-group prod-rg \
  --name web-vm-nic \
  --network-security-group web-nic-nsg

az network vnet subnet update \
  --resource-group prod-rg \
  --vnet-name prod-vnet \
  --name web-subnet \
  --network-security-group web-subnet-nsg
Output
No output on success. Verify with:
az network nic show --name web-vm-nic --resource-group prod-rg --query "networkSecurityGroup.id"
az network vnet subnet show --name web-subnet --resource-group prod-rg --vnet-name prod-vnet --query "networkSecurityGroup.id"
⚠ Order of Evaluation Matters
Subnet NSG is evaluated first, then NIC NSG. If the subnet NSG denies traffic, the NIC NSG never sees it. Conversely, if subnet NSG allows, NIC NSG can still deny. Plan your rules accordingly.
📊 Production Insight
A client had a subnet NSG that allowed SSH from the internet for 'emergency access'. The NIC NSG didn't override it. An attacker exploited that rule. We moved SSH access to a jumpbox with a separate NSG.
🎯 Key Takeaway
Attach NSGs at both subnet and NIC levels for layered security; use ASGs in NIC NSGs for role-based rules.

Service Tags and Application Security Groups: When to Use Which

Service tags represent groups of Azure IP prefixes for services like AzureLoadBalancer, Internet, or Sql. They are used in NSG rules to allow or deny traffic from those services without hardcoding IP ranges. ASGs, on the other hand, represent your own application tiers. Use service tags for external Azure services (e.g., allow AzureLoadBalancer health probes) and ASGs for internal traffic between your VMs. Never use service tags for your own VMs — that's what ASGs are for. A common mistake is using the 'VirtualNetwork' service tag to allow all VNet traffic, which bypasses ASG-based segmentation. Instead, use ASGs to restrict traffic between tiers. For internet-facing rules, use the 'Internet' service tag, but combine with ASGs for the destination.

service-tag-rule.shBASH
1
2
3
4
5
6
7
8
9
10
az network nsg rule create \
  --resource-group prod-rg \
  --nsg-name web-nic-nsg \
  --name AllowLBProbe \
  --priority 100 \
  --direction Inbound \
  --access Allow \
  --protocol Tcp \
  --destination-port-ranges 80 \
  --source-address-prefixes AzureLoadBalancer
Output
{
"name": "AllowLBProbe",
"sourceAddressPrefixes": ["AzureLoadBalancer"],
"priority": 100
}
🔥Service Tags Are Managed by Azure
Azure updates service tags automatically when IP ranges change. You don't need to track Azure IP changes manually. This is a huge maintenance win.
📊 Production Insight
We once used 'VirtualNetwork' service tag to allow all VNet traffic, thinking it was safe. Then a compromised VM in a different subnet could reach the database. Switched to ASGs immediately.
🎯 Key Takeaway
Use service tags for Azure services, ASGs for your own application tiers.

NSG Flow Logs: Debugging and Auditing Traffic

NSG flow logs capture information about IP traffic flowing through an NSG. They are stored in Azure Storage and can be analyzed with Traffic Analytics or third-party tools. In production, enable flow logs on critical NSGs to debug connectivity issues and detect anomalies. For example, if a VM can't reach the internet, flow logs will show whether the traffic was allowed or denied by the NSG. Flow logs are not real-time — expect a 1-2 minute delay. They also incur storage costs, so only enable on NSGs you actively monitor. Use Traffic Analytics to visualize flows and identify patterns like port scanning. I recommend enabling flow logs on all NSGs attached to production subnets, with a retention policy of 30 days.

enable-flow-logs.shBASH
1
2
3
4
5
6
7
8
az monitor flow-log create \
  --resource-group NetworkWatcherRG \
  --name app-nsg-flowlog \
  --nsg app-nsg \
  --storage-account flowlogsstorage \
  --retention 30 \
  --traffic-analytics true \
  --workspace /subscriptions/.../workspaces/LogAnalyticsWorkspace
Output
{
"name": "app-nsg-flowlog",
"enabled": true,
"retentionPolicy": {
"days": 30,
"enabled": true
},
"flowAnalyticsConfiguration": {
"networkWatcherFlowAnalyticsConfiguration": {
"enabled": true,
"workspaceId": "..."
}
}
}
💡Flow Logs Are Cheap Insurance
📊 Production Insight
During a security incident, flow logs showed a denied outbound connection to a known malicious IP. That alerted us to a compromised VM before data exfiltration occurred.
🎯 Key Takeaway
NSG flow logs provide visibility into allowed and denied traffic; enable them on production NSGs.

Common NSG Anti-Patterns in Production

Over the years, I've seen several recurring mistakes with NSGs. First, using overly broad source/destination prefixes like '0.0.0.0/0' or 'Any' when a more specific range would do. This violates least privilege. Second, creating too many rules — NSGs have a limit of 1000 rules (including defaults). Use ASGs and service tags to reduce rule count. Third, not documenting rule purpose. A rule named 'AllowSomething' with no description is a maintenance nightmare. Fourth, applying NSGs only at subnet level and ignoring NIC level. This gives no per-VM granularity. Fifth, forgetting to update NSGs when adding new services. Always pair infrastructure-as-code with NSG changes. Finally, not testing NSG rules before production — use az network nsg rule list and test connectivity with a tool like tcping.

test-nsg-connectivity.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Test connectivity from a VM to a port
# Install tcping on the source VM first
tcping -t 5 10.0.1.4 8080

# Or use Azure's Network Watcher
az network watcher test-connectivity \
  --resource-group NetworkWatcherRG \
  --source-resource /subscriptions/.../resourceGroups/prod-rg/providers/Microsoft.Compute/virtualMachines/web-vm \
  --destination-resource /subscriptions/.../resourceGroups/prod-rg/providers/Microsoft.Compute/virtualMachines/app-vm \
  --destination-port 8080 \
  --protocol Tcp
Output
{
"connectionStatus": "Reachable",
"hops": [
{
"address": "10.0.1.4",
"resourceId": "/.../app-vm",
"nextHopIds": [],
"issues": []
}
]
}
⚠ Rule Limits Are Real
Each NSG can have up to 1000 rules (including defaults). If you approach that limit, consolidate rules using ASGs or service tags. Otherwise, you'll hit deployment failures.
📊 Production Insight
A team once used '0.0.0.0/0' for outbound to 'save time'. A VM got compromised and exfiltrated data to an external server. We now enforce outbound rules with explicit prefixes and deny all by default.
🎯 Key Takeaway
Avoid broad prefixes, too many rules, and lack of documentation; test connectivity before production.

Automating NSG and ASG Management with Infrastructure as Code

Manual NSG management doesn't scale. Use Terraform, Bicep, or ARM templates to define NSGs and ASGs as code. This ensures consistency, auditability, and version control. For example, define an NSG with rules that reference ASGs by name. When you deploy a new VM, assign it to the appropriate ASG in the same template. This couples security with deployment. In production, I recommend using Bicep for its simplicity and modularity. Store NSG definitions in a separate module and reuse across environments. Use parameters for environment-specific values like allowed IP ranges. Always run what-if operations before applying changes to catch unintended rule modifications. CI/CD pipelines should validate NSG rules against a baseline to prevent drift.

nsg-asg.bicepBICEP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
param location string = resourceGroup().location
param env string = 'prod'

resource webAsg 'Microsoft.Network/applicationSecurityGroups@2021-02-01' = {
  name: '${env}-web-asg'
  location: location
}

resource appAsg 'Microsoft.Network/applicationSecurityGroups@2021-02-01' = {
  name: '${env}-app-asg'
  location: location
}

resource nsg 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
  name: '${env}-app-nsg'
  location: location
  properties: {
    securityRules: [
      {
        name: 'AllowWebToApp'
        properties: {
          priority: 200
          direction: 'Inbound'
          access: 'Allow'
          protocol: 'Tcp'
          destinationPortRange: '8080'
          sourceApplicationSecurityGroups: [
            { id: webAsg.id }
          ]
        }
      }
    ]
  }
}

output nsgId string = nsg.id
Output
{
"nsgId": "/subscriptions/.../resourceGroups/prod-rg/providers/Microsoft.Network/networkSecurityGroups/prod-app-nsg"
}
💡Use Bicep Modules for Reusability
Create a module for NSG rules and another for ASGs. Then compose them in your main template. This keeps your code DRY and testable.
📊 Production Insight
We once had a manual change to an NSG that wasn't reflected in the IaC. Next deployment overwrote it, causing an outage. Now we enforce that all NSG changes go through the IaC pipeline.
🎯 Key Takeaway
Define NSGs and ASGs in IaC (Bicep/Terraform) for consistency, version control, and automated validation.

Monitoring and Alerting on NSG Changes

NSG changes can have immediate security and connectivity impacts. You need to monitor them. Use Azure Policy to enforce that NSGs have required rules (e.g., deny all inbound from internet). Use Azure Monitor alerts on NSG rule changes via Activity Log. For example, create an alert when a rule with priority < 100 is created or modified. Also, monitor NSG flow logs for denied traffic spikes — that could indicate a misconfiguration or an attack. In production, I set up a dashboard showing top denied flows per NSG. Combine with Azure Sentinel for advanced threat detection. Remember that NSG changes are logged in the Activity Log with a 15-minute delay. For real-time detection, use Event Hubs and stream to a SIEM.

alert-nsg-change.shBASH
1
2
3
4
5
az monitor activity-log alert create \
  --resource-group prod-rg \
  --name NSGChangeAlert \
  --condition category=Administrative operationName=Microsoft.Network/networkSecurityGroups/write \
  --action-group /subscriptions/.../resourceGroups/prod-rg/providers/microsoft.insights/actionGroups/ops-team
Output
{
"name": "NSGChangeAlert",
"enabled": true,
"scopes": ["/subscriptions/..."],
"condition": {
"allOf": [
{
"field": "category",
"equals": "Administrative"
},
{
"field": "operationName",
"equals": "Microsoft.Network/networkSecurityGroups/write"
}
]
}
}
🔥Activity Log Alerts Are Free
You don't pay for Activity Log alerts, only for the action group notifications (email/SMS). Set them up for all critical NSGs.
📊 Production Insight
An alert fired when a junior admin accidentally deleted a deny rule. We reverted within minutes, preventing a potential data exposure. Without the alert, it would have gone unnoticed until the next audit.
🎯 Key Takeaway
Monitor NSG changes via Activity Log alerts and flow logs to detect misconfigurations and attacks.

Troubleshooting NSG Connectivity Issues

When a VM can't connect, NSGs are often the culprit. Start by checking effective security rules: az network nic show-effective-nsg. This shows the combined rules from subnet and NIC NSGs. Look for a deny rule that matches the traffic. If you see an allow rule but traffic is still blocked, check for network virtual appliances (NVAs) or user-defined routes (UDRs) that might be routing traffic differently. Also verify that the destination VM's NSG allows inbound traffic. Use Network Watcher's IP flow verify to test a specific flow. For outbound issues, check if the source NSG allows outbound traffic to the destination. Remember that NSGs are stateful — if you allow inbound, outbound response is automatic. If you see asymmetric routes, NSGs might block return traffic.

effective-rules.shBASH
1
2
3
4
az network nic show-effective-nsg \
  --resource-group prod-rg \
  --name web-vm-nic \
  --query "value[?direction=='Inbound' && access=='Deny']"
Output
[
{
"access": "Deny",
"destinationPortRange": "0-65535",
"direction": "Inbound",
"sourceAddressPrefix": "0.0.0.0/0",
"sourcePortRange": "0-65535",
"protocol": "*"
}
]
⚠ Effective Rules Show the Truth
Don't rely on the NSG definition alone — effective rules show the actual rules applied after aggregation. Always check this first.
📊 Production Insight
A VM couldn't reach the internet despite an outbound allow rule. Effective rules showed a subnet NSG with a deny all outbound that we forgot about. The NIC NSG allow was irrelevant because subnet NSG blocked first.
🎯 Key Takeaway
Use effective security rules and IP flow verify to diagnose NSG-related connectivity issues.

NSG Best Practices for Multi-Tier Applications

For a typical web-app-db architecture, use separate subnets per tier, each with its own NSG. The web subnet NSG allows inbound HTTP/HTTPS from the internet (using service tag 'Internet') and outbound to the app subnet on the app port. The app subnet NSG allows inbound from the web ASG on the app port and outbound to the db subnet on the db port. The db subnet NSG allows inbound from the app ASG on the db port and denies all other inbound. Use ASGs to reference the tiers instead of IPs. This pattern scales: you can add more VMs to an ASG without changing NSG rules. Also, consider using Azure Firewall for centralized egress control and logging. NSGs are per-subnet/NIC, while Azure Firewall is a managed service that can inspect traffic at the VNet level.

multi-tier-nsg.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Web subnet NSG
az network nsg rule create --nsg-name web-nsg --name AllowHTTP --priority 100 --direction Inbound --access Allow --protocol Tcp --destination-port-ranges 80 --source-address-prefixes Internet
az network nsg rule create --nsg-name web-nsg --name AllowOutToApp --priority 200 --direction Outbound --access Allow --protocol Tcp --destination-port-ranges 8080 --destination-asgs app-asg

# App subnet NSG
az network nsg rule create --nsg-name app-nsg --name AllowInFromWeb --priority 100 --direction Inbound --access Allow --protocol Tcp --destination-port-ranges 8080 --source-asgs web-asg
az network nsg rule create --nsg-name app-nsg --name AllowOutToDb --priority 200 --direction Outbound --access Allow --protocol Tcp --destination-port-ranges 1433 --destination-asgs db-asg

# DB subnet NSG
az network nsg rule create --nsg-name db-nsg --name AllowInFromApp --priority 100 --direction Inbound --access Allow --protocol Tcp --destination-port-ranges 1433 --source-asgs app-asg
az network nsg rule create --nsg-name db-nsg --name DenyAllOtherIn --priority 3000 --direction Inbound --access Deny --protocol * --destination-port-ranges * --source-address-prefixes *
Output
Rules created successfully.
💡Use Separate Subnets for Each Tier
This gives you clear boundaries and makes NSG rules easier to reason about. Avoid mixing tiers in the same subnet.
📊 Production Insight
We had a three-tier app where the app tier could reach the database directly. After a compromise, the attacker accessed customer data. We segmented with NSGs and ASGs, limiting blast radius.
🎯 Key Takeaway
Design NSGs per tier with ASGs for inter-tier communication; use separate subnets for isolation.

Evolving Beyond NSGs: When to Use Azure Firewall or NVAs

NSGs are great for simple allow/deny rules, but they lack advanced features like application-level filtering, TLS inspection, or intrusion detection. For production environments with compliance requirements (PCI-DSS, HIPAA), consider Azure Firewall or a third-party NVA. Azure Firewall is a managed, stateful firewall with built-in threat intelligence and FQDN filtering. It can inspect outbound traffic and log all flows. NSGs still have a role — they provide per-subnet filtering at low cost. Use NSGs for east-west traffic within a VNet and Azure Firewall for north-south traffic (inbound from internet, outbound to internet). This hybrid approach balances cost and security. For example, use NSGs to allow web-to-app traffic, and Azure Firewall to restrict outbound to approved FQDNs.

azure-firewall-rule.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
az network firewall policy rule-collection-group create \
  --resource-group prod-rg \
  --policy-name fw-policy \
  --name default \
  --priority 100

az network firewall policy rule-collection-group collection add-filter-collection \
  --resource-group prod-rg \
  --policy-name fw-policy \
  --rcg-name default \
  --name AllowOutboundHTTP \
  --rule-type ApplicationRule \
  --action Allow \
  --priority 200 \
  --rule-name AllowMicrosoft \
  --source-addresses '*' \
  --protocols http=80 https=443 \
  --fqdn-list '*.microsoft.com'
Output
{
"name": "AllowOutboundHTTP",
"ruleType": "ApplicationRule",
"action": "Allow",
"priority": 200
}
🔥Azure Firewall Is Not a Replacement for NSGs
They complement each other. Use NSGs for subnet-level filtering and Azure Firewall for centralized, advanced inspection. Both can coexist.
📊 Production Insight
A client needed to block outbound traffic to non-approved domains for PCI compliance. NSGs couldn't do FQDN filtering, so we deployed Azure Firewall. NSGs still handled internal segmentation.
🎯 Key Takeaway
Use NSGs for simple per-subnet filtering; add Azure Firewall or NVAs for advanced inspection and compliance.

NSG Diagnostics with Network Watcher: Pinpointing Rule Conflicts

Azure Network Watcher's NSG diagnostics tool lets you check and troubleshoot security rules applied to your Azure traffic through NSGs and Azure Virtual Network Manager. Instead of manually tracing through dozens of rules, you input source/destination IP, port, protocol, and direction, and the tool evaluates all applied security rules — including subnet NSG, NIC NSG, and Azure Virtual Network Manager security admin rules — and tells you exactly which rule allows or denies the traffic. It also shows the effective rule hierarchy, so you can see if a subnet NSG rule is being overridden by a NIC NSG rule or vice versa. In production, use NSG diagnostics as your first troubleshooting step for connectivity issues. It's faster than manually inspecting effective routes and NSG rules. Common findings: an NSG at the subnet level allows traffic but the NIC NSG denies it, or a Virtual Network Manager rule unexpectedly overrides a custom NSG rule. The tool also suggests remediation — you can add a new security rule directly from the diagnostic results page. This is especially useful for Azure Bastion connectivity issues, where misconfigured NSGs frequently block the Bastion subnet traffic.

nsg-diagnostics.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
# Run NSG diagnostics from Network Watcher
az network watcher test-nsg-diagnostics \
  --resource-group NetworkWatcherRG \
  --target-resource /subscriptions/.../resourceGroups/prod-rg/providers/Microsoft.Compute/virtualMachines/web-vm \
  --direction Inbound \
  --protocol TCP \
  --source-address 10.0.1.0/26 \
  --destination-port 80

# Output shows all evaluated rules and which one matched
az network watcher test-nsg-diagnostics show \
  --ids /subscriptions/.../NetworkWatcherRG/providers/Microsoft.Network/networkWatchers/eastus/nsgDiagnostics/web-vm-inbound
💡Diagnose Before Digging
Instead of manually reading through NSG rules, use NSG diagnostics to get a definitive answer. It evaluates all layers: subnet NSG, NIC NSG, and Virtual Network Manager rules.
📊 Production Insight
We spent 3 hours debugging a connectivity issue before discovering NSG diagnostics. It revealed in 30 seconds that a Virtual Network Manager security admin rule — not our custom NSG — was denying traffic. We fixed the admin rule and connectivity was restored.
🎯 Key Takeaway
NSG diagnostics in Network Watcher provides definitive rule evaluation across all security layers, pinpointing exactly which rule allows or denies traffic.

Azure Policy for NSG and Flow Log Governance at Scale

Managing NSGs manually across dozens of subscriptions doesn't scale. Azure Policy provides built-in policies to enforce NSG configuration, ensure flow logs are enabled, and validate traffic analytics configuration. Key built-in policies include: 'Network Watcher flow logs should have traffic analytics enabled' (audits existing flow logs), 'Configure network security groups to use specific workspace, storage account and flow log retention policy for traffic analytics' (DeployIfNotExists — auto-configures flow logs on NSGs), and 'Configure network security groups to enable traffic analytics' (similar but doesn't overwrite existing settings). In production, assign these policies at the subscription or management group level to enforce consistent monitoring across all NSGs. Use the audit policy first to identify non-compliant NSGs, then create remediation tasks to auto-configure flow logs and traffic analytics. Policy assignments can target specific regions using parameters. Remediation tasks use managed identities with Contributor permissions on the target resources. Also enforce that NSGs have required rules (e.g., deny all inbound from internet) using custom policy definitions. This prevents configuration drift and ensures every new NSG is properly monitored from day one.

assign-nsg-policy.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
# Assign built-in policy to enforce traffic analytics on NSGs
az policy assignment create \
  --name 'enforce-nsg-flowlogs' \
  --policy 'Configure network security groups to use specific workspace, storage account and flow log retention policy for traffic analytics' \
  --scope /subscriptions/00000000-0000-0000-0000-000000000000 \
  --params '{
    "networkSecurityGroupRegion": {"value": "eastus"},
    "storageResourceId": {"value": "/subscriptions/.../storageAccounts/flowlogsstorage"},
    "workspaceResourceId": {"value": "/subscriptions/.../workspaces/law-prod"},
    "workspaceRegion": {"value": "eastus"},
    "workspaceId": {"value": "workspace-guid"},
    "retentionDays": {"value": 30},
    "trafficAnalyticsProcessingIntervalInMinutes": {"value": 10}
  }' \
  --assign-identity \
  --location eastus

# Check compliance
az policy state list \
  --policy-assignment 'enforce-nsg-flowlogs' \
  --query "[?complianceState=='NonCompliant']"
🔥DeployIfNotExists vs Audit
Use Audit policies first to discover non-compliant NSGs without making changes. Then switch to DeployIfNotExists with remediation tasks to auto-configure. This prevents unexpected changes.
📊 Production Insight
After an audit found 30% of NSGs had no flow logs enabled, we deployed the DeployIfNotExists policy with remediation. Within 24 hours, all 200+ NSGs across 5 subscriptions had traffic analytics enabled automatically.
🎯 Key Takeaway
Azure Policy enforces NSG flow log configuration and traffic analytics across all subscriptions, preventing monitoring gaps and configuration drift.
NSG vs ASG: Scope and Use Comparing network security groups and application security groups Network Security Group Application Security Group Scope Subnet or NIC level VM NIC level only Rule Definition IP addresses, ports, protocols Logical grouping of VMs Management Manual IP management Automated via VM tags Use Case Perimeter and subnet filtering Micro-segmentation within tiers Complexity Higher with many IPs Lower with logical groups THECODEFORGE.IO
thecodeforge.io
Azure Nsg Asg

NSG Limits, Quotas, and Scaling Considerations

NSGs and ASGs have hard limits that affect production architectures. Each NSG can have up to 1000 security rules (including default rules). Each Azure subscription can have up to 200 ASGs per region. Each NIC can be associated with up to 20 ASGs. NSG flow logs have a throughput limit — in high-traffic subnets, flow logs may drop packets at extreme volumes. If you approach the 1000-rule limit, consolidate using ASGs (each ASG reference counts as one rule regardless of how many VMs are in the group) or service tags. Also use larger CIDR blocks instead of multiple individual IP rules. For high-traffic production subnets (>1 Gbps), consider VNet flow logs instead of NSG flow logs — they have higher throughput capacity. Azure Policy can alert when NSG rule counts approach limits. Monitor NSG rule count using Azure Resource Graph. If you exceed 20 ASGs per NIC, consider using Azure Firewall with application rule groups for role-based access instead. Plan your rule priority scheme early: use 100-499 for critical allow rules, 500-2999 for standard rules, 3000-4095 for deny rules. This leaves room to insert rules without renumbering existing ones.

check-nsg-limits.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# Check NSG rule count
az network nsg show \
  --resource-group prod-rg \
  --name app-nsg \
  --query "length(securityRules)"

# Check ASG count per subscription
az network asg list \
  --resource-group prod-rg \
  --query "length(@)"

# Check ASGs per NIC
az network nic show \
  --resource-group prod-rg \
  --name web-vm-nic \
  --query "length(ipConfigurations[0].applicationSecurityGroups)"
⚠ Rule Limit is Per NSG
The 1000-rule limit includes default rules (6 default rules consume 6 slots). If you have subnet and NIC NSGs on the same VM, each has its own limit. Plan accordingly.
📊 Production Insight
A team hit the 1000-rule limit on their production NSG during a deployment, causing the deployment to fail. We consolidated 300 IP-based rules into 15 ASG-based rules and recovered within an hour.
🎯 Key Takeaway
NSG and ASG limits (1000 rules/NSG, 200 ASGs/subscription, 20 ASGs/NIC) require active monitoring and rule consolidation strategies.
⚙ Quick Reference
15 commands from this guide
FileCommand / CodePurpose
create-nsg.shaz network nsg create \Why Network Security Groups Are Not Optional
list-nsg-rules.shaz network nsg rule list \NSG Rule Evaluation
create-asg.shaz network asg create \Application Security Groups
attach-nsg-nic.shaz network nic update \Combining NSGs and ASGs for Defense in Depth
service-tag-rule.shaz network nsg rule create \Service Tags and Application Security Groups
enable-flow-logs.shaz monitor flow-log create \NSG Flow Logs
test-nsg-connectivity.shtcping -t 5 10.0.1.4 8080Common NSG Anti-Patterns in Production
nsg-asg.bicepparam location string = resourceGroup().locationAutomating NSG and ASG Management with Infrastructure as Cod
alert-nsg-change.shaz monitor activity-log alert create \Monitoring and Alerting on NSG Changes
effective-rules.shaz network nic show-effective-nsg \Troubleshooting NSG Connectivity Issues
multi-tier-nsg.shaz network nsg rule create --nsg-name web-nsg --name AllowHTTP --priority 100 --...NSG Best Practices for Multi-Tier Applications
azure-firewall-rule.shaz network firewall policy rule-collection-group create \Evolving Beyond NSGs
nsg-diagnostics.shaz network watcher test-nsg-diagnostics \NSG Diagnostics with Network Watcher
assign-nsg-policy.shaz policy assignment create \Azure Policy for NSG and Flow Log Governance at Scale
check-nsg-limits.shaz network nsg show \NSG Limits, Quotas, and Scaling Considerations

Key takeaways

1
NSGs are free, stateful firewalls
Attach them to every subnet and NIC in production. Default deny inbound, allow outbound, and explicitly permit only necessary traffic.
2
ASGs decouple security from IPs
Group VMs by role and reference ASGs in NSG rules. This makes rules portable and scalable as your infrastructure changes.
3
Use defense in depth
Attach NSGs at both subnet and NIC levels. Combine with ASGs for role-based rules and Azure Firewall for advanced inspection when needed.
4
Automate and monitor
Define NSGs and ASGs in IaC (Bicep/Terraform). Monitor changes via Activity Log alerts and flow logs to detect misconfigurations and attacks early.

Common mistakes to avoid

3 patterns
×

Not planning nsg asg properly before deployment

Fix
Design your architecture with redundancy, scaling, and security in mind from the start.
×

Ignoring Azure best practices for nsg asg

Fix
Follow Microsoft's Well-Architected Framework and review Azure Advisor recommendations regularly.
×

Overlooking cost implications of nsg asg

Fix
Set budgets and alerts, right-size resources, and use Azure pricing calculator before deploying.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
Explain Network Security Groups & ASGs and its use cases.
Q02JUNIOR
How does Network Security Groups & ASGs handle high availability?
Q03JUNIOR
What are the security best practices for nsg asg?
Q04JUNIOR
How do you optimize costs for nsg asg?
Q05JUNIOR
Compare Azure nsg asg with self-hosted alternatives.
Q01 of 05JUNIOR

Explain Network Security Groups & ASGs and its use cases.

ANSWER
Microsoft Azure — Network Security Groups & ASGs is an Azure service for managing nsg asg in the cloud. Use it when you need reliable, scalable nsg asg without managing underlying infrastructure.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
What is the difference between an NSG and an ASG?
02
Can I attach an NSG to both a subnet and a NIC at the same time?
03
How do I troubleshoot a connectivity issue caused by an NSG?
04
What are the limits of NSGs and ASGs?
05
When should I use Azure Firewall instead of NSGs?
06
How do I monitor NSG changes in production?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Drawn from code that ran under real load.

Follow
Verified
production tested
July 12, 2026
last updated
1,983
articles · all by Naren
🔥

That's Azure. Mark it forged?

8 min read · try the examples if you haven't

Previous
Virtual Network (VNet)
16 / 55 · Azure
Next
Azure Firewall & Firewall Manager