Azure VNET Integration Doesn’t Mean Your Resources Are Private

Most audit, design workshops, and architecture reviews have some version of the same moment. Someone points at a diagram, taps the App Service box, and says “that’s fine, it’s got VNet integration.”

The box gets a tick, the review moves on, and 6 months later a pen test (normally driven by a security incident that was only found when the performance of the App became seriously degraded) finds the same App Service answering requests on its public azurewebsites.net hostname from anywhere on the internet.

VNet integration and network isolation are not the same thing, and Azure’s naming does nothing to help tell them apart. VNet integration is about where your traffic can go. Private Endpoints are about who can reach you.

This post works through the confusion service by service, then covers the other part of the puzzle: once inbound and outbound are both locked down, the PaaS service still has to be told to route outbound traffic to a firewall or NVA that can actually see it.

This post also briefly touches on Subnet Delegation but does not go into this in detail. If you want a deeper dive on that, check out my post on that topic here.

Two Doors

In an everyday real-world scenario, think of a PaaS resource as having two separate doors, similar to any airport you’ve ever had the pleasure of passing through. There is one door which everyone enters through (Departures because you need to get somewhere, and anyone can go through those doors until they need to show a boarding pass at security to prove they are allowed to board their flight), and a separate door which everyone exits through (Arrivals, from where you then set off to either remember where you’ve parked, or else head for the nearest taxi, bus or train).

In PaaS, the inbound door controls who can call the resource, and by default it faces the internet through a shared, multi-tenant public endpoint. Locking it down means giving the resource a private IP inside your VNet and turning the public endpoint off, which on Azure is almost always done with a Private Endpoint backed by Azure Private Link.

The outbound door controls where the resource’s own traffic goes when it calls something else: a database, a storage account, a downstream API. Regional VNet integration solves this one, giving the compute a presence inside a delegated subnet so its outbound calls can reach VNet-resident resources, respect NSGs and UDRs, and use custom DNS.

VNet integration only opens the outbound door. Microsoft’s own documentation for App Service is blunt about it: virtual network integration “gives your app access to resources in your virtual network, but it doesn’t grant inbound private access to your app,” and is “used only to make outbound calls from your app into your virtual network.”

Enable VNet integration on an App Service, an API Management instance, or a Logic App, and its public inbound endpoint keeps answering exactly as it did before. Locking down the inbound side is a separate, additional piece of configuration, and for most PaaS services that means Private Endpoints.

App Service and Functions

Let’s start with App Service and Functions (on Premium or Elastic Premium plans) as they share the same regional VNet integration model, so the same rules apply to both along with some additional granular controls.

Turning on VNet Integration gets the app talking to VNet-resident resources, peered VNets, and anything reachable over service or private endpoints.

This does nothing for inbound traffic though. An App Service with VNet integration switched on is still fully reachable at its public hostname unless a Private Endpoint is added separately and, usually, public network access disabled on the app itself.

There’s a second surprise on the outbound side that catches even people who know about the inbound gap. By default, regional VNet integration only routes RFC1918 traffic (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) through the VNet. Everything else, including calls to the public internet, still leaves the platform directly. Routing all outbound traffic through the VNet, so it can be inspected by a firewall, filtered by NSGs, or forced through a NAT gateway, has to be explicitly turned on.

The current mechanism is the outboundVnetRouting.allTraffic=true property on the site. This means that both app and configuration traffic (image pulls, content share, backup and restore) is routed for inspection:

az resource update --resource-group <group-name> --name <app-name> \
--resource-type "Microsoft.Web/sites" \
--set properties.outboundVnetRouting.allTraffic=true

One thing to note here, you can go to granular levels here if you need to. You can use the narrower applicationTraffic=true (application traffic only) setting, which means configuration traffic stays on the public route. You can also enable the imagePullTraffic, contentShareTraffic, backupRestoreTraffic, or managedIdentityTraffic properties individually, which is useful when you want to use specific traffic types without forcing everything else through the VNet.

The older vnetRouteAllEnabled site property and WEBSITE_VNET_ROUTE_ALL app setting still work for backwards compatibility, but the recommendation is to use outboundVnetRouting since it can be audited with a built-in Azure Policy definition.

Full details can be found here.

API Management: the source of all confusion…..

API Management is where this causes the most confusion, because the tier names make the wrong assumption about what is possible.

Standard v2 and Premium v2 both support VNet integration for outbound connectivity to isolated backends. On Standard v2, that’s the only VNet option available, and it is explicitly outbound-only: the gateway, management plane, and developer portal all remain publicly accessible.

Getting the front door private needs either an inbound Private Endpoint, available across most tiers including Standard v2.

APIM Premium (Classic) adds another layer of confusion with VNet injection, which means the APIM instance is deployed directly into the APIM Delegated Subnet for full isolation.

This then gets even more confusing when you get to Premium v2: an NSG is still required on the subnet, but it collapses roughly a dozen rules (load-balancer health probes, Traffic Manager, Storage, SQL, Entra ID, Event Hub, certificate-chain hosts) down to essentially one — an outbound allow to Azure Key Vault (plus whatever your own backends need).

Logic Apps Standard

Logic Apps Standard makes the split between inbound and outbound unusually explicit, because Azure’s own documentation for it describes them as two separate features you configure separately: “Setting up virtual network integration affects only outbound traffic. To secure inbound traffic, which continues to use the App Service shared endpoint, review Set up inbound traffic through private endpoints.“

VNet integration gets a workflow’s HTTP actions and connector calls routed privately, but does nothing to the trigger endpoint a partner system calls to start the workflow: that stays on the shared public endpoint until a Private Endpoint is added. The reverse holds too, since adding a Private Endpoint for inbound doesn’t touch outbound traffic. Both are genuinely needed, configured independently, for a Logic App that’s private in both directions.

Service Bus: Off By Default and SKU-dependent

Service Bus is one of the great annoyances across the range of Azure services because private networking capabilites are only available by selecting the highest and most expensive SKU that the service offers.

Private Endpoints and VNet service endpoints both require the Premium tier; Basic and Standard namespaces can’t use either. Provisioning at Premium doesn’t switch anything off on its own, though. The publicNetworkAccess property defaults to Enabled, so the namespace answers over the internet using its access keys until someone explicitly sets it to Disabled.

A Premium namespace with a Private Endpoint attached but publicNetworkAccess left on default isn’t privately reachable only, it’s reachable both ways, defeating the point of paying for Premium at all.

Application Gateway: Isn’t that Public?

Application Gateway flips the pattern deliberately: its job is to be the public entry point in front of things made private everywhere else, sitting between the internet and a backend pool that itself uses Private Endpoints.

The gotcha here isn’t VNet integration, it’s DNS. When the backend pool target is an App Service or API Management instance reached through its Private Endpoint, Application Gateway still needs to resolve that service’s hostname to the private endpoint IP, not the public one. Resolve to the public IP and health probes and traffic either fail outright or silently route around the private path.

Getting this right means a Private DNS Zone linked to the gateway’s VNet with an A record pointing the service’s hostname at the Private Endpoint’s IP, checked and verified, not assumed.

Of course, confusion reigns again with Application Gateway as you have the ability to deploy a Private instance to service traffic on a private frontend IP linked to your VNET with no Public IP on the frontend. The same rules apply though, if DNS is not set up correctly, backends can be reached on their public endpoints.

Getting Outbound Traffic Back to Azure Firewall

Everything above deals with whether traffic goes into or out of the VNet at all. The remaining half is making sure that once outbound traffic is in the VNet, it actually reaches the inspection point rather than routing around it.

The mechanism is a User Defined Route on the integration subnet with a 0.0.0.0/0 destination and a next hop of the Azure Firewall’s private IP. For App Service and Functions specifically, this only works once Route All is also enabled, because a 0.0.0.0/0 UDR is meaningless to traffic the platform never sent into the VNet in the first place. Deploying the firewall requires a dedicated AzureFirewallSubnet of at least a /26, and forced tunneling of internet-bound traffic also needs an AzureFirewallManagementSubnet, since forced tunneling removes the firewall’s own ability to route its management traffic out the regular path.

Two things always go wrong once this is wired up. Longest prefix match wins, always: Azure injects system routes for the VNet’s own address space with a next hop of “Virtual Network” automatically, and because a route like 10.0.0.0/16 is more specific than a 0.0.0.0/0 UDR, intra-VNet traffic keeps flowing directly between subnets regardless of the default route.

168.63.129.16 ignores your route table, and Microsoft’s documentation is explicit that it “isn’t subject to user defined routes.” It carries platform traffic (DNS resolution, VM agent heartbeats, load balancer health probes) and a 0.0.0.0/0 route to the firewall will never see it. It’s not a gap that you need to close, but it does mean “all outbound traffic goes through the firewall” is never literally true.

Inbound vs Outbound by Service

ServiceMinimum SKUInbound privacyOutbound privacy
App Service / FunctionsBasic (web apps); Premium/Elastic Premium (Functions)Private Endpoint + disable public accessRegional VNet integration + Route All
API ManagementStandard v2 (outbound only); Premium/Premium v2 (full isolation)Inbound Private Endpoint, or VNet injection (Premium/Premium v2)VNet integration (Standard v2, Premium v2)
Logic Apps StandardAny Standard planPrivate EndpointVNet integration
Service BusPremiumPrivate EndpointSame Private Endpoint, or VNet service endpoints
Application GatewayStandard_v2 / WAF_v2Private frontend IP (optional)N/A, it’s the entry point

Conclusion

The pattern across every service is the same: Azure gives you granular, composable controls, and in line with the Shared Responsibility model pushes the responsibility back on you to implement these controls in line with your own privacy and security requirements.

Deploying a service that contains VNet Integration capabilities does not mean you can call it done. VNet Integration and Network Isolation are not the same thing. In summary:

  • VNet integration is a routing control for outbound calls, not a privacy control.
  • Private Endpoints are the privacy control, and a separate, additional step for every service above.
  • Route All and the firewall UDR are a third, independent layer deciding whether outbound traffic actually reaches the inspection point built for it.

Top Highlights from Microsoft Ignite 2024: Key Azure Announcements

This year, Microsoft Ignite was held in Chigaco for in-person attendees as well as virtually with key sessions live streamed. As usual, the Book of News was released to show the key announcements and you can find that at this link.

From a personal standpoint, the Book of News was disappointing as at first glance there seemed to be very few key annoucements and enhancements being provided for core Azure Infrastructure and Networking.

However, there were some really great reveals that were announced at various sessions throughout Ignite, and I’ve picked out some of the ones that impressed me.

Azure Local

Azure Stack HCI is no more ….. this is now being renamed to Azure Local. Which makes a lot more sense as Azure managed appliances deployed locally but still managed from Azure via Arc.

So, its just a rename right? Wrong! The previous iteration was tied to specific hardware that had high costs. Azure Local now brings low spec and low cost options to the table. You can also use Azure Local in disconnected mode.

More info can be found in this blog post and in this YouTube video.

Azure Migrate Enhancements

Azure Migrate is product that has badly needed some improvements and enhancements given the capabilities that some of its competitors in the market offer.

The arrival of a Business case option enables customers to create a detailed comparison of the Total Cost of Ownership (TCO) for their on-premises estate versus the TCO on Azure, along with a year-on-year cash flow analysis as they transition their workloads to Azure. More details on that here.

There was also an announcement during the Ignite Session around a tool called “Azure Migrate Explore” which looked like it provides you with a ready-made Business case PPT template generator that can be used to present cases to C-level. Haven’t seen this released yet, but one to look out for.

Finally, one that may hae been missed a few months ago – given the current need for customers to migrate from VMware on-premises deployments to Azure VMware Solution (which is already built in to Azure Migrate via either Appliance or RVTools import), its good to see that there is a preview feature around a direct path from VMware to Azure Stack HCI (or Azure Local – see above). This is a step forward for customers who need to keep their workloads on-premises for things like Data Residency requirements, while also getting the power of Azure Management. More details on that one here.

Azure Network Security Perimeter

I must admit, this one confused me a little bit at first glance but makes sense now.

Network Security Perimeter allows organizations to define a logical network isolation boundary for PaaS resources (for example, Azure Storage acoount and SQL Database server) that are deployed outside your organization’s virtual networks.

So, we’re talking about services that are either deployed outside of a VNET (for whatever reason) or are using SKU’s that do not support VNET integration.

More info can be found here.

Azure Bastion Premium

This has been in preview for a while but is now GA – Azure Bastion Premium offers enhanced security features such as private connectivity and graphical recordings of virtual machines connected through Bastion.

Bastion offers enhanced security features that ensure customer virtual machines are connected securely and to monitor VMs for any anomalies that may arise.

More info can be found here.

Security Copilot integration with Azure Firewall

The intelligence of Security Copilot is being integrated with Azure Firewall, which will help analysts perform detailed investigations of the malicious traffic intercepted by the IDPS feature of their firewalls across their entire fleet using natural language questions. These capabilities were launched on the Security Copilot portal and now are being integrated even more closely with Azure Firewall.

The following capabilities can now be queried via the Copilot in Azure experience directly on the Azure portal where customers regularly interact with their Azure Firewalls: 

  • Generate recommendations to secure your environment using Azure Firewall’s IDPS feature
  • Retrieve the top IDPS signature hits for an Azure Firewall 
  • Enrich the threat profile of an IDPS signature beyond log information 
  • Look for a given IDPS signature across your tenant, subscription, or resource group 

More details on these features can be found here.

DNSSEC for Azure DNS

I was surprised by this annoucement – maybe I had assumed it was there as it had been available as an AD DNS feature for quite some time. Good to see that its made it up to Azure.

Key benefits are:

  • Enhanced Security: DNSSEC helps prevent attackers from manipulating or poisoning DNS responses, ensuring that users are directed to the correct websites. 
  • Data Integrity: By signing DNS data, DNSSEC ensures that the information received from a DNS query has not been altered in transit. 
  • Trust and Authenticity: DNSSEC provides a chain of trust from the root DNS servers down to your domain, verifying the authenticity of DNS data. 

More info on DNSSEC for Azure DNS can be found here.

Azure Confidential Clean Rooms

Some fella called Mark Russinovich was talking about this. And when that man talks, you listen.

Designed for secure multi-party data collaboration, with Confidential Clean Rooms, you can share privacy sensitive data such as personally identifiable information (PII), protected health information (PHI) and cryptographic secrets confidently, thanks to robust trust guarantees that safeguard your data throughout its lifecycle from other collaborators and from Azure operators.

This secure data sharing is powered by confidential computing, which protects data in-use by performing computations in hardware-based, attested Trusted Execution Environments (TEEs). These TEEs help prevent unauthorized access or modification of application code and data during use. 

More info can be found here.

Azure Extended Zones

Its good to see this feature going into GA and hopefully will provide a pathway for future AEZ’s in other locations.

Azure Extended Zones are small-footprint extensions of Azure placed in metros, industry centers, or a specific jurisdiction to serve low latency and data residency workloads. They support virtual machines (VMs), containers, storage, and a selected set of Azure services and can run latency-sensitive and throughput-intensive applications close to end users and within approved data residency boundaries. More details here.

.NET 9

Final one and slightly cheating here as this was announced at KubeCon the week before – .NET9 has been announced. Note that this is a STS release with an expiry of May 2026. .NET 8 is the current LTS version with an end-of-support date of November 2026 (details on lifecycles for .NET versions here).

Link to the full release announcement for .NET 9 (including a link to the KubeCon keynote) can be found here.

Conclusion

Its good to see that in the firehose of annoucements around AI and Copilot, there there are still some really good enhancements and improvements coming out for Azure services.

100 Days of Cloud — Day 16: Azure Firewall

Its Day 16 of 100 Days of Cloud and todays post is about Azure Firewall.

Firewall …. we’ve covered this before haven’t we? Well, yes in a way. In a previous post, I talked about Network Security Groups and how they can be used to filter traffic in and out of a Subnet or a Network Interface in a Virtual Network.

Azure Firewall v NSG

Azure Firewall is a Microsoft-managed Network Virtual Appliance (NVA). This appliance allows you to centrally create, enforce and monitor network security policies across Azure subscriptions and virtual networks (vNets). An NSG is a layer 3–4 Azure service to control network traffic to and from a vNet.

Unlike Azure Firewall, an NSG can only be associated with subnets or network interfaces within the same subscription of Azure VMs. Azure Firewall can control a much broader range of network traffic. It can filter and analyze L3-L4 traffic, as well as L7 application traffic.

Azure Firewall sits at the subscription level and manages traffic going in and out of the vNet. The NSG is then deployed at the subnet level and network interface. The NSG then manages traffic between subnets and virtual machines.

Azure Firewall Features

Azure Firewall includes the following features:

  • Built-in high availability — so no more need for load balancers.
  • Availability Zones — Azure Firewall can span availability zones for greater availability.
  • Unrestricted cloud scalability — Azure Firewall can scale to accommodate changing traffic flows.
  • Application FQDN filtering rules — You can limit outbound HTTP/S traffic or Azure SQL traffic to a specified list of fully qualified domain names (FQDN) including wild cards
  • Network traffic filtering rules — Allow/Deny Rules
  • FQDN tags — makes it easy for you to allow well-known Azure service network traffic through your firewall.
  • Service tags — groups of IP Addresses.
  • Threat intelligence — can identify malicious IP Addresses or Domains.
  • Outbound SNAT support — All outbound virtual network traffic IP addresses are translated to the Azure Firewall public IP.
  • Inbound DNAT support — Inbound Internet network traffic to your firewall public IP address is translated (Destination Network Address Translation) and filtered to the private IP addresses on your virtual networks.
  • Multiple public IP addresses — You can associate up to 250 Public IPs with your Azure Firewall.
  • Azure Monitor logging — All events are integrated with Azure Monitor.
  • Forced tunneling — route all Internet traffic to a designated next hop.
  • Web categories — lets administrators allow or deny user access to web site categories such as gambling websites, social media websites, and others.
  • Certifications — PCI/SOC/ISO Compliant.

Azure Firewall and NSG in Conjuction
NSGs and Azure Firewall work very well together and are not mutually exclusive or redundant. You typically want to use NSGs when you are protecting network traffic in or out of a subnet. An example would be a subnet that contains VMs that require RDP access (TCP over 3389) from a Jumpbox. Azure Firewall is the solution for filtering traffic to a VNet from the outside. For this reason, it should be deployed in it’s own VNet and isolated from other resources. Azure Firewall is a highly available solution that automatically scales based on its workload. Therefore, it should be in a /26 size subnet to ensure there’s space for additional VMs that are created when it’s scaled out.

A scenario to use both would be a Hub-spoke VNet environment with incoming traffic from the outside. Consider the following diagram:

The above model has Azure Firewall in the Hub VNet which has peered connections to two Spoke VNets. The Spoke Vnets are not directly connected, but their subnets contain a User Defined Route (UDR) that points to the Azure Firewall, which serves as a gateway device. Also, Azure Firewall is public facing and is responsible for protecting inbound and outbound traffic to the VNet. This is where features like Application rules, SNAT and DNaT come in handy.

Conclusion

If you have a simple environment, then NSGs should be sufficient for network protection. However for large scale Production environments, Azure Firewall provides a far greater scale of protection.

Hope you enjoyed this post, until next time!!