Application Security Groups in Azure

Imagine writing a firewall rule that says “allow traffic from web servers to database servers” — using those exact words, not a list of IP addresses. Application Security Groups make that possible in Azure. They are logical labels you attach to VM network interfaces, and then reference those labels in NSG rules.

The problem with IP-based NSG rules

Traditional NSG rules look like this: “allow traffic from 10.0.1.5, 10.0.1.6, 10.0.1.7 to port 1433.” That works until your web tier scales from 3 VMs to 30. Now you have 30 IP addresses to manage in every NSG rule that references the web tier.

When VMs are added or removed, someone needs to update the NSG rules. That person might be you at 2am responding to an incident. IP-based rules don’t scale, they drift, and they are hard to read.

Application Security Groups (ASGs) replace those IP addresses with named groups. The NSG rule says “allow traffic from the asg-web-servers group to the asg-db-servers group on port 1433.” When you add a new web server, you add it to the ASG — no NSG rule changes needed.

How ASGs work

An ASG is a named resource with no configuration other than its name and region. You create it, then add VM network interfaces to it. The ASG itself does nothing — it is simply a group identifier that NSG rules can reference.

The workflow is:

1. Create an ASG resource (for example, asg-web-servers).

2. Assign the ASG to the network interface of each VM that plays that role.

3. Write NSG rules that use the ASG as the source or destination instead of IP addresses.

When you deploy a new web server VM, you assign it to asg-web-servers. It immediately inherits all the network permissions defined in NSG rules that reference that ASG. No rule updates needed.

Creating and using ASGs with the CLI

Create ASGs for a three-tier application:

# Create ASGs for each application tier
az network asg create \
  --name asg-web-servers \
  --resource-group rg-prod-networking \
  --location eastus

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

az network asg create \
  --name asg-db-servers \
  --resource-group rg-prod-networking \
  --location eastus

Assign an ASG to an existing VM’s network interface:

# Get the NIC name for a VM
az vm show \
  --name vm-web-01 \
  --resource-group rg-prod-compute \
  --query "networkProfile.networkInterfaces[0].id" \
  --output tsv

# Assign the ASG to the NIC (use the NIC name from above)
az network nic ip-config update \
  --name ipconfig1 \
  --nic-name vm-web-01VMNic \
  --resource-group rg-prod-compute \
  --application-security-groups asg-web-servers

When creating a new VM, assign the ASG at creation time:

az vm create \
  --name vm-web-02 \
  --resource-group rg-prod-compute \
  --image Ubuntu2204 \
  --vnet-name vnet-prod-eastus-001 \
  --subnet snet-web \
  --asgs asg-web-servers \
  --public-ip-address "" \
  --admin-username azureuser \
  --generate-ssh-keys

Writing NSG rules that reference ASGs

Once your VMs are assigned to ASGs, you can write clean, readable NSG rules:

# Allow web servers to reach app servers on port 8080
az network nsg rule create \
  --name Allow-Web-to-App \
  --nsg-name nsg-app-tier \
  --resource-group rg-prod-networking \
  --priority 100 \
  --direction Inbound \
  --protocol Tcp \
  --source-asgs asg-web-servers \
  --destination-asgs asg-app-servers \
  --destination-port-ranges 8080 \
  --access Allow

# Allow app servers to reach database servers on SQL port
az network nsg rule create \
  --name Allow-App-to-DB \
  --nsg-name nsg-data-tier \
  --resource-group rg-prod-networking \
  --priority 100 \
  --direction Inbound \
  --protocol Tcp \
  --source-asgs asg-app-servers \
  --destination-asgs asg-db-servers \
  --destination-port-ranges 1433 \
  --access Allow

# Deny direct web-to-DB traffic (defense in depth)
az network nsg rule create \
  --name Deny-Web-to-DB \
  --nsg-name nsg-data-tier \
  --resource-group rg-prod-networking \
  --priority 200 \
  --direction Inbound \
  --protocol Tcp \
  --source-asgs asg-web-servers \
  --destination-asgs asg-db-servers \
  --destination-port-ranges 1433 \
  --access Deny

These rules read like English. Anyone looking at the NSG immediately understands the intent without needing to look up what 10.0.1.7 is.

VMs in multiple ASGs

A VM’s network interface can belong to more than one ASG. This is useful when a VM plays multiple roles or when you have cross-cutting concerns like monitoring.

# Assign a VM to both the app-servers ASG and a monitoring-targets ASG
az network nic ip-config update \
  --name ipconfig1 \
  --nic-name vm-app-01VMNic \
  --resource-group rg-prod-compute \
  --application-security-groups asg-app-servers asg-monitoring-targets

Now your monitoring NSG rule can simply say “allow from monitoring agents to asg-monitoring-targets on port 9100” — regardless of whether those targets are web servers, app servers, or anything else.

Tip

Create functional ASGs like asg-monitoring-targets, asg-backup-targets, and asg-patch-targets in addition to tier-based ASGs. These cross-cutting groups let you apply operational policies cleanly without per-IP rules.

Limitations to know

ASGs have a few constraints worth knowing before you design your rules:

Same VNet only. All NICs in an ASG must be in the same VNet. You cannot group VMs from different VNets into one ASG.

Same region. ASGs are regional resources. A VM in East US cannot join an ASG in West Europe.

NSG and ASG must be in the same subscription. You cannot reference an ASG from a different subscription in an NSG rule.

List all ASGs in a resource group to review your current groups:

az network asg list \
  --resource-group rg-prod-networking \
  --output table

Common mistakes

  1. Forgetting to assign new VMs to the ASG. The biggest risk with ASGs is that a new VM deployment skips the ASG assignment. The VM then doesn’t match the NSG rules you expect, and either traffic is blocked or the VM is unprotected. Enforce ASG assignment through IaC templates and deployment pipelines.
  2. Mixing IP ranges and ASGs in the same rule. An NSG rule can use either source IP ranges or a source ASG — not both. If you need to cover both, write two separate rules. Trying to combine them in one rule will result in an error.
  3. Creating ASGs but not using them in any rules. An ASG with no NSG rules referencing it does nothing. Periodically audit your ASGs and remove ones that are no longer referenced in any rule, to keep your configuration clean.

Frequently asked questions

What is the difference between an ASG and an NSG?

An NSG is the firewall — it contains the allow/deny rules. An ASG is a logical group of VMs that you reference inside NSG rules. ASGs make NSG rules readable and maintainable by replacing IP addresses with meaningful group names like "web-servers" or "db-servers".

Can a VM belong to multiple ASGs?

Yes. A single network interface can be a member of multiple ASGs. This lets you apply overlapping rule sets. For example, a VM could belong to both an "app-servers" ASG and a "monitoring-targets" ASG.

Do ASGs work across VNets?

No. ASGs are scoped to a single VNet. A VM in VNet A cannot be added to an ASG in VNet B. For cross-VNet security policies, you need to use IP ranges or service tags in your NSG rules.

Last verified: 19 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.