There's one problem I run into in Azure projects over and over again. Network security gets handled late. Network Security Groups (NSGs) are copied from one place to the next, exceptions pile up, and after a while the environment is a patchwork of rules that don't match. Then the first pentest comes along and everyone starts scrambling. Azure Virtual Network Manager (AVNM) and its security admin rules changed that for me. They give you central network guardrails that teams simply can't work around. If you've ever used them to block inbound RDP and SSH across the board, you know how much calmer that makes you.
Security admin rules are evaluated before NSGs and always win on Deny
The thing that sets security admin rules apart is where they sit in packet processing. They are evaluated before any NSGs on every subnet, and they are enforced without exception. When a security admin rule denies traffic, no NSG can override it. That gives you an actual org-wide safeguard. If you want inbound RDP or SSH from the internet blocked everywhere, you configure it once here instead of in every subnet or VNet.
The diagram below shows the order in which traffic is evaluated. Security admin rules come first, local NSGs after them:
flowchart TD
Internet["Internet"] --> Guardrails["Security admin rules"]
Guardrails --> NSG["Network Security Group"]
NSG --> Subnet["Subnet"]
Figure: Security admin rules filter traffic before NSGs are even consulted, which is what makes them work as global guardrails.
For a more detailed technical overview with additional examples, see the AVNM documentation and the concept page on security admin rules.
Scope and dynamic network groups decide which VNets are covered
An AVNM instance is always scoped to a subscription or a management group. Within that scope you create network groups. These are either static, with VNets you pick by hand, or dynamic and managed by Azure Policy. In larger environments the dynamic option makes a huge difference. When VNets are created or moved, policy conditions such as tags or name patterns put them into the right group automatically. You avoid manual drift, and new networks are protected from day one.
A setup I come across a lot in customer environments:
- Scope: Production management group
- Network group: All-prod-vnets (dynamic, tag Environment=Prod)
- Security admin rule: Deny inbound TCP 3389/22 from 0.0.0.0/0
Pro tip: Put your critical guardrails on dynamic network groups (with Azure Policy). That way coverage stays consistent as the environment grows.
Security admin rules are deployed region by region
NSGs don't work this way, but security admin rules are deployed per region. Once you push a configuration, the rules apply to every subnet in the group within that region, and nobody has to do anything locally. The workflow felt unusual to me at first. Each change targets one specific region and group, and for multi-region governance that turns out to be a real advantage.
Always use a dedicated test group and test network when you try things out. Nothing reaches production until you explicitly deploy it to the right region and network group.
# Example: Deploying a security admin rule via PowerShell (requires Az module 11+, Network Contributor rights)
New-AzNetworkManagerSecurityAdminRuleCollection -Name "Deny-RDP-SSH" -NetworkManagerName "MyAVNM" -ResourceGroupName "rg-avnm" -Region "westeurope" -Rule {
SourceAddressPrefix = "0.0.0.0/0"
DestinationPortRanges = @("3389", "22")
DestinationAddressPrefix = "*"
Protocol = "Tcp"
Action = "Deny"
}
This creates a Deny rule for inbound RDP and SSH traffic from the internet in the targeted region and group.
Allow, Deny and Always Allow behave very differently
Admins who are new to AVNM often trip over the difference between Deny, Allow and Always Allow. A "Deny" rule is final, and no NSG can permit that traffic. An "Allow" rule lets traffic pass unless a later NSG blocks it, which makes it the right choice for explicit exceptions. "Always Allow" is a special override that lets traffic through even if a following NSG would block it. Use it rarely and only for narrowly scoped requirements, because it effectively switches off one layer of defense.
In day-to-day work I use Deny to shut high-risk ports like RDP, SSH or SQL across the whole estate. Allow doesn't come up often, but it helps for special subnets such as Bastion or jump hosts that need an exception from the blanket deny.
Monitoring shows whether a rule actually blocks traffic
Whenever I roll out a new security admin rule, I want to see it working in practice and not only on a change ticket. So I spin up a test VM in the affected group, run Test-NetConnection (or an external port scan) and look at the results. Azure Monitor Network Insights is also handy for spotting blocked flows quickly.
If you need more detail, send the subnets' flow logs to a Log Analytics workspace. There you can check whether connection attempts to blocked ports are dropped the way you expect.
Field tip: Check that policy really assigns new VNets to the correct security admin rules. Look in the AVNM portal for each region. I've found unexpected gaps that way more than once.
Security admin rules turn guardrails into real controls
Security admin rules in AVNM solve a governance problem every cloud team knows, which is giving teams self-service while keeping central control over networking. They provide something NSGs alone never could, namely network guardrails that are consistent and can't be broken. Together with dynamic group membership and policy integration, they let you scale securely without managing every subnet by hand. If you haven't started with AVNM yet, I'd do it now rather than wait for the next pentest to surprise you.


