For years the move was grim and predictable. You needed to stop one /24 from leaking to on-premises, so you deployed a network virtual appliance, a whole VM, licensed, patched, monitored, HA-paired across zones, whose entire reason to exist was to say no to a single prefix. Or you gave up and wrote a PowerShell runbook that reconciled route tables on a timer and prayed nobody touched it.
Route maps for Azure Route Server reached general availability across the Azure public cloud. The sidecar-NVA-as-a-filter pattern is dead. Let me build up why from zero, because the mechanism is simple once you see it, and because the announcement copy papers over exactly one thing you’ll trip on in six months.
First, what Route Server even is
Start with BGP, because everything here hangs off it. BGP is how routers gossip. Each router tells its neighbours “here are the networks I can reach,” the neighbours pass it on, and over a few seconds everyone agrees on a map of who can get where. In Azure, when you connect a virtual network to on-premises over ExpressRoute or a VPN gateway, that gossip is how your VNet learns your datacentre’s routes and vice versa.
Now drop a network virtual appliance into that VNet, an SD-WAN box, a firewall, a custom router. Historically it had no way to join the conversation. Azure’s software-defined network didn’t speak BGP to arbitrary VMs, so your NVA couldn’t advertise routes to Azure, and Azure couldn’t tell the NVA what it knew. People bridged the gap with static routes and user-defined route tables, updated by hand or by script. It was as fun as it sounds.
Azure Route Server is the fix. It’s a managed BGP speaker, think of it as the office receptionist who knows everyone’s extension. Your NVA peers with it, the ExpressRoute and VPN gateways in the VNet peer with it automatically, and Route Server reflects routes between all of them. Critically, it is not in the data path. No packet ever transits a Route Server. It’s a matchmaker for routes, not a hop. It runs on Azure’s backbone with a fixed, well-known ASN, the Route Server documentation on Microsoft Learn gives you the value (65515 at the time of writing); confirm it there rather than hard-coding it from memory. That’s the whole product.
The problem it shipped with: all or nothing
Route Server did its job faithfully and completely. That was the trouble. Every route a peer advertised, it accepted. Every route it knew, it re-advertised to every other peer. There was no knob for “learn this but don’t pass it on,” no “advertise this prefix but make it less attractive,” no “drop that management subnet before it ever reaches the WAN.”
So you had three bad options: a filtering NVA, a prefix-list hack on the on-prem routers (now your routing policy lives in two clouds and a datacentre), or scripts. Route maps replace all three for a wide class of hybrid scenarios.
Route maps: match, then act
A route map is an ordered list of rules. Each rule has two halves:
- Match criteria, what the rule looks for in a route: a route prefix (one or more CIDRs), a BGP community value, or an AS path, evaluated against a match condition such as equals/not-equals/contains.
- Actions, what to do with a matched route: drop it entirely, or add, replace, or remove BGP attributes. That means AS-path prepending to make a path look worse, or stamping and stripping BGP communities so downstream routers can act on tags.
I’m deliberately not reciting the exact enum spelling of every match condition and action here, the supported set is listed in the Route Server route-maps documentation, and it’s the kind of thing that gets an addition between the time I write this and the time you read it. Pull the current vocabulary from the docs and build against that. What’s worth saying is what’s not in it: there is no matching on DSCP, port, or anything in the packet. Route maps operate on routing information, not traffic. If you came here looking for a stateful firewall, you still need a firewall.
The other concept that bites people is direction, and it’s defined from the Route Server’s point of view, not yours:
- Inbound, applied to routes Route Server receives from the peer. This is your filter on what the NVA is allowed to inject into Azure (and, by extension, propagate onward).
- Outbound, applied to routes Route Server sends to the peer. This controls what the NVA gets told about.
A route map is attached to a specific BGP peering, in one direction. In my testing, and matching how the feature is documented, each peering takes one inbound map and one outbound map, so treat it as two policy slots per NVA rather than an unlimited pipeline. If that association model matters to your design, verify it against your own peering before you commit, because tested behaviour and documented behaviour can still drift from your topology.
The part the announcement is quiet about
Here’s the core use case, filtering a specific subnet so it never advertises to on-premises over ExpressRoute, and here’s the honest version. Route maps live on the Route Server–to-NVA peering. They do not attach to the ExpressRoute gateway. You cannot drop a route a Route Server hands to an ExpressRoute circuit with a route map; that’s still ExpressRoute route-filter territory.
What you can do, and it’s the common real scenario, is this. Your NVA originates or relays a set of prefixes. One of them, say your out-of-band management subnet 10.50.7.0/24, must never reach on-prem. Put an inbound route map on the NVA’s peering that drops 10.50.7.0/24. Route Server never learns it, so it never reflects it to the ExpressRoute gateway, so it never leaves Azure. The filter sits one hop earlier than you were imagining, but the result is identical and you’ve deleted a VM to get it.
The outbound mirror image is just as useful: stop advertising your full on-prem route table to a chatty SD-WAN appliance that only needs a default route, and you’ve cut its routing table, and its churn, dramatically.
Configuring it
Portal path: your Route Server resource → Peerings → pick the peering → associate an inbound and/or outbound route map, and author the rules there. This is the most complete surface today; CLI and IaC parity for the route-map object itself still lags the portal, which is normal for a freshly-GA feature.
The Route Server and peering plumbing underneath is scriptable and stable:
For the route map as code, the object is a child of the Route Server’s underlying hub. Pin the current GA API version yourself, I’m not going to quote one I can’t verify, and neither should your template:
You then reference the route map, inbound or outbound, on the BGP connection. Do the association as a reviewed change, a mis-scoped Contains on a short prefix can black-hole far more than you meant. Run it through what-if and check learned routes before and after.
The limits nobody prints on the box
Route Server has hard ceilings, and they’re the numbers that usually constrain a real design: a maximum number of BGP peers, a cap on routes advertised per peer, and, for route maps, a maximum number of rules per map plus the one-per-direction-per-peering association model. The Route Server limits documentation currently lists 8 peers and up to 1,000 routes per peer, but treat every one of those figures as “verify before you architect” rather than gospel; service limits move, and I’d rather you check than design against a number I half-remembered. The posture is the same for all of them. And if you’re anywhere near any of these caps, stop: a route map with thirty hand-rolled rules is a policy you’ve outgrown, and you should be summarising prefixes or rethinking the topology, not adding rule thirty-one.
If you tested this in preview
Route maps are declarative resources, so the ones you built in preview carry over, there’s no data-plane cutover to schedule. The housekeeping: drop any preview feature registration you enabled to get in early, confirm your maps still show as associated after the GA rollout, and re-run list-learned-routes / list-advertised-routes on each peering to prove the filters still fire. Don’t assume; verify the route exchange, because “it worked in preview” is how outages introduce themselves.
On availability: this is GA across the Azure public cloud, all regions. I’m not going to tell you it’s live in Azure Government or the sovereign clouds, because I can’t confirm it is, check your region’s feature list before you promise it to a regulated workload.
The win here isn’t glamorous and that’s the point. Route maps don’t do anything a competent network engineer couldn’t already do with BGP policy. They just let you do it inside Azure, on the managed BGP speaker you already pay for, instead of standing up an appliance whose only talent was rejection. Delete the NVA. Keep the receipts.