Centralize Egress Through Azure Firewall
Build a hub-spoke network with Azure Firewall controlling all outbound traffic.
Introduction
30 Second Summary
Every company wants to know exactly what leaves its network. Without a central checkpoint, each workload can reach any destination on the internet, making it nearly impossible to spot data leaks or block malicious connections.
In this project, you will build a hub-spoke network on Azure where all outbound internet traffic from a workload VM routes through a central Azure Firewall for inspection and filtering.
What You'll Build
A hub-spoke network architecture with centralized egress control, where a Firewall Policy selectively allows traffic to specific destinations while blocking everything else.
By the end of this project, you'll have:
- A hub virtual network with Azure Firewall deployed as the single egress point for all spoke workloads.
- A spoke virtual network peered to the hub, with a workload VM whose outbound traffic is forced through the firewall via a User-Defined Route.
- A working Firewall Policy with application rules (FQDN filtering) and network rules that you have tested against allowed and blocked destinations.
- Secret Mission: Add a second spoke and configure firewall-inspected spoke-to-spoke communication.
Are there any prerequisites?
You need an Azure subscription with permissions to create resources (Owner or Contributor role). A free Azure account with $200 credit works perfectly for this project.
Create the Hub Virtual Network and Deploy Azure Firewall
Every centralized egress architecture starts with a hub network. This is the virtual network that hosts shared security services, like a firewall, and acts as the single exit point for all outbound traffic.
In this step, you will create the hub virtual network, deploy Azure Firewall inside it, and set up Azure Bastion for secure access to your workload VMs later.
In this step, get ready to:
- Create the resource group and hub virtual network.
- Deploy Azure Firewall with a Firewall Policy.
- Deploy Azure Bastion in the hub for secure VM access.
Create the resource group and hub virtual network
A resource group is a container that holds all the Azure resources for this project. The hub virtual network is where your firewall will live.
- Sign in to the Azure portal.
- In the search box at the top of the portal, type Resource group.
- Select Resource groups in the search results.
- Select + Create.
- In the Basics tab, select your Azure subscription.
- For Resource group, enter FW-Egress-RG.
- For Region, select a region such as East US.
- Select Review + create, then select Create.
Now create the hub virtual network inside this resource group.
- In the search box at the top of the portal, type Virtual network.
- Select Virtual networks in the search results.
- Select + Create.
- On the Basics tab, select your subscription and choose FW-Egress-RG as the resource group.
- For Name, enter Hub-VNet.
- For Region, select the same region you chose for the resource group.
- Select Next twice to get to the IP Addresses tab.
- For the IPv4 Address space, accept or enter 10.0.0.0/16.
- Under Subnets, select the default subnet to edit it.
- In the Edit subnet pane, set Subnet purpose to Azure Firewall.
- For Starting address, enter 10.0.1.0.
- Select Save.
- Select Review + create, then select Create.
What is AzureFirewallSubnet?
When you set the subnet purpose to Azure Firewall, Azure automatically names the subnet AzureFirewallSubnet. This is a required naming convention. Azure Firewall will only deploy into a subnet with this exact name.
The subnet must also be at least /26 in size (64 addresses). The default /26 satisfies this requirement.
Don't see the Azure Firewall option in Subnet purpose?
Make sure you are on the IP Addresses tab (not the Basics or Security tabs). The subnet purpose dropdown appears when you select the default subnet to edit it.
If the option still doesn't appear, try selecting a different region that supports Azure Firewall Standard. Help me find the Azure Firewall subnet purpose option.
Deploy Azure Firewall with a Firewall Policy
Azure Firewall is the managed network security service that will inspect and control all outbound traffic from your spoke networks. A Firewall Policy holds the rules that define what traffic is allowed or denied.
- In the search box at the top of the portal, type Firewall.
- Select Firewalls in the search results, then select + Create.
- On the Create a Firewall page, select your subscription and choose FW-Egress-RG as the resource group.
- For Name, enter Egress-FW.
- For Region, select the same region as your resource group.
- For Firewall SKU, select Standard.
- For Firewall management, select Use a Firewall Policy to manage this firewall.
- Under Firewall policy, select Add new.
- Enter Egress-Policy as the policy name and select the same region.
- Select OK to create the policy.
- For Choose a virtual network, select Use existing, then select Hub-VNet.
- For Public IP address, select Add new, enter fw-pip as the name, and select OK.
- Clear the Enable Firewall Management NIC check box.
- Select Review + create, then select Create.
Why does deployment take so long?
Azure Firewall deployment typically takes 5 to 10 minutes. This is normal because Azure is provisioning dedicated compute, networking, and storage resources for the firewall instance.
Cost awareness
Azure Firewall Standard costs $1.25 per hour while deployed. Complete this project and delete all resources within 1-2 hours to keep your total cost under $4.
Once deployment finishes, you need to note the firewall's private IP address. You will use it in a later step to route traffic.
- Navigate to your FW-Egress-RG resource group and select the Egress-FW firewall.
- On the Overview page, locate the Private IP field and note this address down (it will look something like 10.0.1.4).
Write it down
Copy the private IP to a notepad or sticky note. You will enter this IP when creating the route table in Step 3.
Deploy Azure Bastion in the hub
Azure Bastion provides secure, browser-based SSH access to virtual machines without exposing them with a public IP. You will use it later to connect to your workload VM for testing.
- In the search box at the top of the portal, type Bastion.
- Select Bastions in the search results, then select + Create.
- Select your subscription and choose FW-Egress-RG as the resource group.
- For Name, enter Hub-Bastion.
- For Region, select the same region you used previously.
- For Tier, select Developer.
- For Virtual network, select Hub-VNet.
- Select Review + create, then select Create.
What about AzureBastionSubnet?
When you deploy Bastion into a virtual network, Azure automatically creates a subnet named AzureBastionSubnet for you. You do not need to create it manually.
Wait for the Bastion deployment to finish before moving on. This typically takes a few minutes.
Bastion deployment failing?
Make sure you selected the Developer tier. Higher tiers require additional configuration such as a dedicated public IP for Bastion itself.
Also confirm you selected Hub-VNet as the virtual network. Bastion must be deployed in the same VNet where your firewall lives. Help me troubleshoot my Bastion deployment.
Your hub network is fully set up. You have a firewall ready to inspect traffic and Bastion ready for secure VM access. Next, you will create the spoke network and a workload VM that the firewall will protect.
Create the Spoke Virtual Network and Workload VM
Your hub network is ready with Azure Firewall standing guard. Now you need something for it to protect.
In a hub-spoke topology, workloads live in spoke virtual networks that are isolated from the hub. The spoke connects to the hub through Virtual Network Peering, which lets traffic flow between the two networks without traversing the public internet. In this step, you will create a spoke network, peer it to the hub, and deploy a VM that will serve as your test workload.
In this step, get ready to:
- Create a spoke virtual network with a workload subnet.
- Peer the spoke to the hub so traffic can flow between them.
- Deploy an Ubuntu VM in the spoke with no public IP.
Create the spoke virtual network
The spoke virtual network is where your actual workload lives. It uses a separate address space from the hub so the two networks don't overlap.
- In the Azure portal search bar, type Virtual networks and select it from the results.
- Click Create.
- Select FW-Egress-RG as the resource group.
- Enter Spoke-VNet as the virtual network name.
- Select the same region you used for the hub (e.g., East US).
- Click Next until you reach the IP Addresses tab.
- Set the address space to 10.1.0.0/16.
- Delete any default subnet if one exists.
- Click Add a subnet.
- Enter Workload-SN as the subnet name.
- Set the starting address to 10.1.1.0/24.
- Click Add.
- Click Review + create, then click Create.
Why a separate address space?
The hub uses 10.0.0.0/16 and the spoke uses 10.1.0.0/16. Virtual network peering requires non-overlapping address spaces. If they overlapped, Azure would not know which network a packet belongs to.
Peer the spoke to the hub
Peering creates a direct, low-latency link between two virtual networks. Without it, the spoke has no way to reach the firewall in the hub.
- Once Spoke-VNet is deployed, navigate to it.
- In the left menu, select Peerings.
- Click Add.
- Under This virtual network, enter Spoke-to-Hub as the peering link name.
- Leave Allow forwarded traffic enabled.
- Under Remote virtual network, enter Hub-to-Spoke as the peering link name.
- Select Hub-VNet as the virtual network.
- Confirm Allow forwarded traffic is enabled on the remote side as well.
- Leave all other defaults and click Add.
Why enable forwarded traffic?
When the spoke sends traffic to the internet, it first goes to the firewall in the hub. The firewall inspects it, then forwards it onward. The return traffic follows the reverse path.
Without "Allow forwarded traffic" enabled on both sides, the peering would drop any traffic that the firewall forwards back to the spoke. This setting ensures the firewall can act as a middleman between the spoke and the internet.
After a few seconds, the peering status should show Connected on both sides. You can verify this on the Peerings page of either VNet.
Peering status showing Initiated?
If the status stays at Initiated instead of Connected, the peering was only created on one side. Delete the peering and re-create it, making sure you fill in both the local and remote peering link names in the same form.
help me troubleshoot my VNet peering status
Deploy a workload VM in the spoke
This VM simulates a real workload. It has no public IP address, which means its only path to the internet is through the hub. Once you add a route table in the next step, all its outbound traffic will flow through the firewall.
- In the Azure portal search bar, type Virtual machines and select it.
- Click Create, then select Azure virtual machine.
On the Basics tab:
- Select FW-Egress-RG as the resource group.
- Enter Srv-Workload as the virtual machine name.
- Select the same region as your other resources.
- For Image, select Ubuntu Server 24.04 LTS - x64 Gen2.
- For Size, select Standard_B1s (the cheapest available option).
- For Authentication type, select SSH public key.
- Leave the username as azureuser.
- For SSH public key source, select Generate new key pair.
- Enter srv-workload-key as the key pair name.
Now switch to the Networking tab:
- For Virtual network, select Spoke-VNet.
- For Subnet, select Workload-SN.
- For Public IP, select None.
Why no public IP?
If the VM had its own public IP, it could bypass the firewall entirely and reach the internet directly. Removing the public IP forces all outbound traffic through the hub. This is the whole point of centralized egress control.
- Click Review + create, then click Create.
- A prompt appears asking you to download the private key. Click Download private key and create resource.
- Save the srv-workload-key.pem file somewhere you can find it later. You will need it to connect to the VM via Bastion.
Keep the key file safe
The private key file downloads only once. If you lose it, you will need to reset the VM's SSH credentials. Save it in your Downloads folder or Desktop for now.
Wait for the VM deployment to complete. Once it finishes, navigate to the Srv-Workload resource and confirm that its Public IP address field shows a dash (no public IP assigned).
VM deployment failed?
The most common cause is a quota limit on the Standard_B1s size in your selected region. Try a different region, or check your subscription's vCPU quotas under Subscription > Usage + quotas.
help me troubleshoot my VM deployment failure
Your spoke network is live and peered to the hub. Right now, the VM's outbound traffic can reach the hub, but there is no rule telling it to go through the firewall. In the next step, you will create a route table that forces all internet-bound traffic from the spoke through Azure Firewall.
Force Egress Through the Firewall with a Route Table
Your hub-spoke network is wired up, but traffic from the spoke VM can still take any path to the internet. Azure's default routing sends outbound traffic directly out, bypassing the firewall entirely.
To force all outbound traffic through Azure Firewall, you need a User-Defined Route (UDR). A UDR overrides Azure's default routes and tells the subnet to send all internet-bound traffic to the firewall's private IP address instead.
In this step, get ready to:
- Create a route table for the spoke subnet.
- Add a default route that points all internet traffic to Azure Firewall.
- Associate the route table with the workload subnet to activate the route.
Create the route table
A route table is a collection of rules that tell Azure where to send network traffic. You will create one dedicated to the spoke subnet and later fill it with a route pointing to the firewall.
- In the Azure portal search bar at the top, type Route tables and select Route tables from the results.
- Click + Create.
- Select your subscription.
- For Resource group, select FW-Egress-RG.
- For Region, select the same region you used for your other resources.
- For Name, enter Spoke-RT.
- Leave Propagate gateway routes set to Yes (the default).
- Click Review + create, then click Create.
Why leave Propagate gateway routes on Yes?
This setting controls whether routes from a VPN or ExpressRoute gateway are automatically injected into the route table. This project has no gateway, so the default Yes is harmless.
In a production environment with a gateway, you would set this to No so that on-premises prefixes do not bypass the firewall.
- Wait for the deployment to complete, then click Go to resource.
You should see the Spoke-RT overview page with no routes listed yet.
Don't see FW-Egress-RG in the resource group dropdown?
Make sure the region you selected matches the region where you created FW-Egress-RG. Resource groups themselves are global, but the portal sometimes filters by region context.
Try refreshing the page or clearing any subscription filters at the top of the portal.
Help me find my resource group in the Azure portal.
Add the default route pointing to Azure Firewall
The key to centralized egress is a single route: destination 0.0.0.0/0 (all internet-bound traffic) with the next hop set to the firewall's private IP. This intercepts every outbound request and sends it to Azure Firewall for inspection.
- On the Spoke-RT page, expand Settings in the left menu and select Routes.
- Click + Add.
- For Route name, enter ToFirewall.
- For Destination type, select IP Addresses.
- For Destination IP addresses/CIDR ranges, enter 0.0.0.0/0.
- For Next hop type, select Virtual appliance.
- For Next hop address, enter the private IP address of Egress-FW that you noted in Step 1.
- Click Add.
Why Virtual appliance for a managed service?
Azure Firewall is a fully managed service, but in route table terms you reference it as a "Virtual appliance" with its private IP address. This is by design. Azure uses the Virtual appliance next hop type for any IP-addressed network device that inspects or forwards traffic.
You should now see the ToFirewall route listed with destination 0.0.0.0/0 and next hop showing the firewall's private IP.
Forgot your firewall's private IP?
Navigate to FW-Egress-RG > Egress-FW > Overview. The private IP is displayed in the properties panel on the right side.
Getting a validation error when adding the route?
Double-check that the destination CIDR is exactly 0.0.0.0/0 with no extra spaces. Also confirm the next hop address is a valid private IP (it should start with 10.0. in this project).
Help me fix a route table validation error in the Azure portal.
Associate the route table with the spoke subnet
A route table does nothing until it is associated with a subnet. Once you link Spoke-RT to Workload-SN, every VM in that subnet will have its outbound traffic redirected to the firewall.
- In the left menu of Spoke-RT, select Subnets under Settings.
- Click + Associate.
- For Virtual network, select Spoke-VNet.
- For Subnet, select Workload-SN.
- Click OK.
You should see Workload-SN listed under the Subnets tab of Spoke-RT.
What happens now?
All outbound internet traffic from Workload-SN is now routed to Azure Firewall. The firewall has no rules configured yet, so it drops all traffic by default. Your VM currently cannot reach the internet at all.
In the next step, you will add firewall rules to selectively allow specific traffic through.
Don't see Spoke-VNet in the virtual network dropdown?
The route table and the virtual network must be in the same region. If you created Spoke-RT in a different region than Spoke-VNet, you will need to delete the route table and recreate it in the correct region.
Help me associate my route table with my spoke subnet.
Your spoke subnet is now locked down. All internet-bound traffic goes to the firewall, and the firewall is currently blocking everything. Next up, you will configure firewall rules to selectively allow traffic through.
Configure Firewall Rules to Allow Selective Egress
Right now, the route table is forcing all outbound traffic from the spoke through Azure Firewall. But without any rules configured, the firewall drops everything by default.
In this step, you will add rules to the Firewall Policy that selectively allow specific traffic. You will permit DNS queries so the VM can resolve domain names, and allow HTTPS traffic to www.google.com so you can prove the firewall is inspecting and controlling egress.
In this step, get ready to:
- Add a network rule collection to allow DNS resolution from the spoke.
- Add an application rule collection to allow web traffic to a specific FQDN.
- Update the workload VM's NIC DNS settings to use the allowed DNS servers.
Configure a network rule to allow DNS resolution
Before the VM can reach any website, it needs to resolve domain names to IP addresses. That requires DNS queries on UDP port 53. You will create a network rule that allows the spoke subnet to reach two public DNS servers.
- In the Azure portal, open the FW-Egress-RG resource group.
- Select the Egress-Policy firewall policy.
- In the left menu, expand Settings and select Rules.
- Select the Network rules tab.
- Click Add a rule collection.
Fill in the rule collection details:
- Name: Net-Allow-DNS.
- Priority: 100.
- Rule collection action: Allow.
- Rule collection group: DefaultNetworkRuleCollectionGroup.
Under Rules, fill in the following:
- Name: Allow-DNS.
- Source type: IP Address.
- Source: 10.1.0.0/16.
- Protocol: UDP.
- Destination Ports: 53.
- Destination type: IP address.
- Destination: 209.244.0.3,209.244.0.4.
- Click Add.
- Wait for the deployment notification to complete before continuing.
What does this rule do?
This network rule allows any resource in the 10.1.0.0/16 spoke address space to send UDP packets on port 53 to two public DNS servers (209.244.0.3 and 209.244.0.4).
Without this rule, the VM cannot resolve any domain names because the firewall blocks all outbound traffic by default. DNS resolution is a prerequisite for application-layer rules that use FQDNs.
Don't see the Add button?
Make sure you are in the Egress-Policy firewall policy, not the firewall resource itself. Navigate to Settings > Rules within the policy.
help me find where to add rule collections in my firewall policy
Configure an application rule to allow specific web traffic
Network rules operate at layers 3 and 4 (IP addresses and ports). Application rules operate at layer 7, letting you filter by FQDN (fully qualified domain name). You will add a rule that allows HTTP and HTTPS traffic to www.google.com only.
- Return to the Rules page in Egress-Policy.
- Select the Application rules tab.
- Click Add a rule collection.
Fill in the rule collection details:
- Name: App-Allow-Web.
- Priority: 100.
- Rule collection action: Allow.
Under Rules, fill in the following:
- Name: Allow-Google.
- Source type: IP address.
- Source: 10.1.0.0/16.
- Protocol:port: http,https.
- Destination type: FQDN.
- Destination: www.google.com.
- Click Add.
Why FQDN filtering instead of IP-based rules?
Major websites like Google use many IP addresses that rotate frequently. Filtering by FQDN lets Azure Firewall inspect the HTTP Host header or TLS SNI extension to match the domain name, regardless of which IP address it resolves to.
This is what makes application rules more powerful than network rules for web traffic control. Any FQDN not explicitly listed (like www.microsoft.com) will be blocked.
Deployment taking a long time?
Firewall rule deployments can take 1-2 minutes. Wait for the green success notification before moving on. If it fails, check that you entered the source as 10.1.0.0/16 (the spoke's full address space) and the FQDN as www.google.com with no trailing slash.
help me troubleshoot my firewall rule deployment failure
Update the workload VM's DNS settings
The VM currently uses Azure's default DNS (168.63.129.16), which the firewall blocks. You need to point the VM's network interface at the DNS servers you just allowed in the network rule.
- Return to the FW-Egress-RG resource group.
- Find and select the network interface for Srv-Workload (it will be named something like srv-workload... with a NIC suffix).
- In the left menu under Settings, select DNS servers.
- Select Custom.
- Enter 209.244.0.3 in the first DNS server field.
- Click Add DNS server and enter 209.244.0.4.
- Click Save.
Why set DNS at the NIC level?
Azure VMs inherit DNS settings from their virtual network by default. Setting custom DNS on the NIC overrides this inheritance for just this VM, pointing its DNS queries at the specific servers your firewall rule allows.
If you left the default Azure DNS (168.63.129.16), the VM's DNS queries would go to Azure's internal resolver, which the firewall has no rule for. Those queries would be silently dropped.
Now restart the VM so it picks up the new DNS configuration:
- Return to the FW-Egress-RG resource group and select the Srv-Workload VM.
- Click Restart in the top toolbar.
- Confirm the restart when prompted.
- Wait for the VM status to return to Running.
VM won't restart?
Ensure you are looking at the Srv-Workload virtual machine resource, not the network interface. The Restart button appears on the VM's Overview page in the top command bar.
help me restart my Azure VM
Your firewall policy now has two rule collections: one for DNS at the network layer, and one for web traffic at the application layer. In the next step, you will connect to the VM and prove that allowed traffic passes while everything else is blocked.
Test Egress Control
Your firewall rules are in place. The network rule allows DNS lookups and the application rule permits traffic to www.google.com.
Now it is time to prove the architecture works. You will connect to the workload VM through Azure Bastion and run test requests. If the firewall is doing its job, allowed destinations will respond and everything else will be silently dropped.
In this step, get ready to:
- Connect to the workload VM via Azure Bastion.
- Verify that allowed traffic passes through the firewall.
- Confirm that unauthorized traffic is blocked.
Connect to the workload VM via Bastion
The Srv-Workload VM has no public IP address. The only way to reach it is through Azure Bastion, which provides a browser-based SSH session directly in the Azure portal.
- In the Azure portal, navigate to the FW-Egress-RG resource group.
- Select the Srv-Workload virtual machine.
- At the top of the VM Overview page, click Connect.
- Select Connect via Bastion from the dropdown.
- Set Authentication Type to SSH Private Key from Local File.
- Enter azureuser in the Username field.
- Click the file picker under Local File and select the srv-workload-key.pem file you downloaded earlier.
- Click Connect.
A browser-based terminal opens with an SSH session to your VM.
Why Bastion instead of a public IP?
Azure Bastion lets you access VMs without exposing SSH or RDP ports to the internet. The VM stays completely private with no public IP. All access flows through the Azure portal over a secure TLS channel.
This is critical for the egress test. If the VM had a public IP, you would not be able to confirm that outbound traffic is truly forced through the firewall.
Connection failing?
Make sure you selected the correct .pem file. Azure Bastion requires the private key to be in RSA, DSA, or OPENSSH format.
If you see a timeout, the Bastion Developer tier only supports VMs in the same virtual network. Since Srv-Workload is in the peered Spoke-VNet, confirm that your Bastion deployment completed successfully and VNet peering is active.
help me troubleshoot my Azure Bastion connection to Srv-Workload
Test allowed traffic
Your application rule explicitly allows HTTP and HTTPS traffic to www.google.com. This request should pass through the firewall and return a successful response.
- In the SSH session, test the allowed destination by running:
curl -I https://www.google.com
You should see an HTTP 200 response with headers from Google. This confirms the application rule is working and the firewall is allowing traffic to www.google.com.
What does this command do?
The curl -I command sends an HTTP HEAD request and displays only the response headers. An HTTP 200 status confirms the destination was reachable and responded successfully.
For this to work, two things happen behind the scenes. The network rule allows the VM to resolve the domain name via DNS (UDP port 53). Then the application rule matches the FQDN and permits the HTTPS connection through the firewall.
Not seeing an HTTP 200?
If the command hangs or times out, DNS resolution may be failing. Confirm the VM's NIC has custom DNS servers set to 209.244.0.3 and 209.244.0.4. Also verify the VM was restarted after changing DNS settings.
Check that your network rule in Egress-Policy allows UDP port 53 from 10.1.0.0/16 to those DNS server IPs.
help me troubleshoot why curl to www.google.com is failing through Azure Firewall
Test blocked traffic
Now test a destination that has no matching rule. The firewall denies all traffic by default, so any FQDN not explicitly allowed should be blocked.
- In the same SSH session, test a blocked destination by running:
curl -I https://www.microsoft.com
This command should time out or return an error after approximately 60 seconds. No response comes back because the firewall drops the traffic silently.
Why does it time out instead of giving an error message?
Azure Firewall uses a default-deny approach. When traffic does not match any allow rule, the firewall drops the packets without sending a rejection back to the client. The VM keeps waiting for a response that never arrives, which looks like a timeout.
This is your proof that centralized egress control works. Only traffic matching your firewall rules can leave the spoke network. Everything else is silently blocked.
Secret mission
Add a Second Spoke with Spoke-to-Spoke Communication
In a real enterprise environment, workloads in different spokes often need to communicate with each other. Right now your firewall controls egress to the internet, but what about lateral traffic between spokes? Extend your architecture by adding a second spoke and enabling firewall-inspected spoke-to-spoke communication.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. Azure Firewall Standard charges $1.25 per hour even when idle, so leaving resources running accumulates cost quickly.
Cost warning
Azure Firewall Standard costs $1.25/hour ($30/day) regardless of traffic volume. The VMs and public IP add minor additional costs. If you are not actively experimenting, delete the resource group to stop all charges immediately.
Resources you used:
- Azure Firewall Egress-FW (Standard SKU, ~$1.25/hour).
- Public IP fw-pip (~$0.005/hour).
- VMs Srv-Workload and Srv-Workload2 (Standard_B1s, ~$0.01/hour each).
- Azure Bastion Hub-Bastion (Developer tier).
- Virtual networks Hub-VNet, Spoke-VNet, Spoke2-VNet with peerings (no cost).
- Route tables Spoke-RT and Spoke2-RT (no cost).
- Firewall Policy Egress-Policy.
- SSH private key file srv-workload-key.pem on your local machine.
Keep everything running
No action needed. Choose this if you are still actively experimenting with firewall rules or adding more spokes.
- Be aware the firewall alone costs ~$30/day.
- The SSH key file srv-workload-key.pem remains on your local machine. Store it in a safe location.
Pause - I'll come back to this later
Shut down the VMs to save compute costs. The firewall continues charging because it cannot be paused from the portal alone.
- In the Azure portal, go to your resource group FW-Egress-RG.
- Select Srv-Workload, then click Stop in the top toolbar.
- Repeat for Srv-Workload2.
- Confirm both VMs show Stopped (deallocated) status.
Why does the firewall keep charging?
Azure Firewall Standard does not support a portal-based stop action. Deallocating it requires Azure PowerShell or CLI commands. If you want to stop all charges without deleting, the simplest approach is to delete the entire resource group and recreate it later.
Delete - I don't want to use this again
Remove all project resources and start fresh. Deleting the resource group removes everything in one action.
- In the Azure portal, search for Resource groups and select it.
- Select FW-Egress-RG.
- Click Delete resource group at the top of the page.
- Type FW-Egress-RG in the confirmation field and click Delete.
- Wait for the deletion to complete. This removes the firewall, VMs, VNets, route tables, Bastion, public IP, and firewall policy.
- Delete the srv-workload-key.pem file from your local machine (check your Downloads folder).
How long does deletion take?
Resource group deletion is irreversible and typically takes 5-10 minutes. Azure Resource Manager deletes resources in dependency order automatically.
Nice Work!
Nice Work!
You just built a production-grade egress control architecture from scratch. Every byte of outbound traffic from your spoke workloads now passes through a central Azure Firewall for inspection and policy enforcement.
This is the exact pattern used in Azure Landing Zones and enterprise architectures worldwide. The concepts you practiced transfer directly to production environments at any scale.
You've learned how to:
- Create a hub-spoke network topology with VNet peering and deploy Azure Firewall as the centralized egress point.
- Configure User-Defined Routes to force all outbound traffic from spoke subnets through the firewall.
- Build a Firewall Policy with application rules (FQDN filtering) and network rules, then verify that allowed traffic passes and unauthorized traffic is blocked.
- Add a second spoke and enable firewall-inspected spoke-to-spoke communication through the hub.
Ready to quiz yourself?