
{"id":7491,"date":"2020-12-11T17:14:59","date_gmt":"2020-12-11T17:14:59","guid":{"rendered":"https:\/\/rax-stg-wp-aws.com\/blogs\/implement-azure-bastion-with-vnet-peering\/"},"modified":"2026-11-03T19:28:42","modified_gmt":"2026-11-03T19:28:42","slug":"implement-azure-bastion-with-vnet-peering","status":"publish","type":"blogs","link":"https:\/\/www.rackspace.com\/en-gb\/blogs\/implement-azure-bastion-with-vnet-peering\/","title":{"rendered":"Implement Azure Bastion with VNET peering"},"content":{"rendered":"<p><strong>Introduction<\/strong><br \/>\nMicrosoft\u00ae&nbsp; has finally provided&nbsp;VNET peering support for <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/bastion\/vnet-peering\">Azure Bastion<\/a>. This offering has been a much-anticipated feature release, and I&#8217;m sure many folks are happy to see it available.<\/p>\n<p>Before this release, Azure\u00ae Bastion had an annoying limitation\u2014it was not transitive, so its scope did not extend beyond a single VNET. This meant if you had multiple<br \/>\nVNETs (which most environments typically do), then you&#8217;d need to deploy a Bastion in every VNET that had VMs that you wanted to manage remotely. Fortunately, that&#8217;s a thing of the past, and this new capability makes the service more useful, cheaper, and less complicated.&nbsp;<br \/>\n&nbsp;<br \/>\nMicrosoft has made both regional and global VNET peering available for Azure Bastion, so you can deploy the service in a single VNET and peer with VNETs in any public region around the world regardless of whether they are in the same subscription or not. This ability unlocks the possibility of deploying the Bastion in a common hub-and-spoke topology like the following design:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture1_35.png\" alt=\"azure bastion pic 1\" \/><\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/bastion\/vnet-peering#architecture](https:\/\/docs.microsoft.com\/en-us\/azure\/bastion\/vnet-peering#architecture\">Image Source<\/a>&nbsp;<\/p>\n<p><strong>Wait, what&#8217;s Azure Bastion?<\/strong><\/p>\n<p>For those of you who are new to the Azure Bastion service, I refer you to this&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/bastion\/bastion-overview\">Microsoft documentation<\/a>&nbsp;which does a great job of providing an overview of the product and its purpose.<\/p>\n<p><strong>Implementation walkthrough<\/strong><\/p>\n<p>In this example walkthrough, I use the Azure portal to deploy a Bastion in a hub VNET and show you the steps to successfully establish a connection through peering to target virtual machines (VMs) that reside in spoke VNETs. We will have one target VM in the same region as the Bastion and another Target VM in a different region.<\/p>\n<p><strong>Creation of target VMs in each spoke VNET<\/strong><\/p>\n<p>Because this walkthrough focuses on deploying the Bastion and making the relevant connections, I won&#8217;t bore you with VM creation instructions. Therefore, I have already deployed the following<\/p>\n<p>Windows\u00ae VM:<\/p>\n<ul>\n<li><strong>Name<\/strong>: WindowsVM01<\/li>\n<li><strong>Region<\/strong>: UK South<\/li>\n<li><strong>Public IP<\/strong>: none<\/li>\n<li><strong>NSG<\/strong>: WindowsVM01-nsg&nbsp;<\/li>\n<li><strong>VNET<\/strong>: UKS-VNET01-SPOKE01 (192.168.1.0\/24)<\/li>\n<li><strong>Subnet<\/strong>: UKS-VNET01-SPOKE01-SN01 (192.168.1.0\/27)<\/li>\n<\/ul>\n<p>&nbsp;&nbsp;<\/p>\n<p>Linux\u00ae (Ubuntu operating system) VM:<\/p>\n<ul>\n<li><strong>Name<\/strong>: LinuxVM01<\/li>\n<li><strong>Region<\/strong>: East US<\/li>\n<li><strong>Public IP<\/strong>: none<\/li>\n<li><strong>NSG<\/strong>: LinuxVM01-nsg<\/li>\n<li><strong>VNET<\/strong>: EUS-VNET01-SPOKE01 (192.169.1.0\/24)<\/li>\n<li><strong>Subnet<\/strong>: EUS-VNET01-SPOKE01-SN01 (192.169.1.0\/27)<\/li>\n<\/ul>\n<p><strong>About the Network Security Groups (NSGs)<\/strong><\/p>\n<p>By default, Microsoft associates the NSG to the VM NIC. For ease of management, I prefer to assign the NSGs to the subnet level instead. Therefore, I associated each respective NSG to the corresponding subnet and disassociated it from the VM&#8217;s NIC. The result is:<\/p>\n<p><em>&nbsp; &nbsp; WindowsVM01-nsg &lt;-&gt; UKS-VNET01-SPOKE01-SN01<br \/>\n&nbsp; &nbsp; LinuxVM01-nsg &lt;-&gt; EUS-VNET01-SPOKE01-SN01<\/em><br \/>\n&nbsp;<\/p>\n<p><strong>Create the Bastion host<\/strong><\/p>\n<p>Use the following steps to go through this demo<\/p>\n<ol>\n<li>From the Azure home page, select <strong>+ Create a resource<\/strong>.<\/li>\n<li>Type `<em>Bastion<\/em>`. On the <strong>Results<\/strong>&nbsp;page, you should see the Bastion icon (verify the publisher is Microsoft) and click <strong>Create<\/strong>.<\/li>\n<li>On the <strong>Create a Bastion<\/strong>&nbsp;page, create or choose an existing resource group, give the&nbsp;Bastion a name, and select a region.<\/li>\n<li>For the VNET, I created a new one called <strong>UKS-VNET02-HUB01<\/strong>. The Azure Bastion subnet&nbsp;must be <strong>\/27<\/strong>&nbsp;or larger, so I made the VNET big enough to accommodate this by choosing&nbsp;<strong>192.168.2.0\/24<\/strong>.<\/li>\n<li>For the Bastion subnet, Microsoft requires you to call it <strong>AzureBastionSubnet<\/strong>&nbsp;and&nbsp;make it at least \/27, as mentioned already.&nbsp;This subnet is a dedicated subnet for the Bastion only, meaning you&nbsp;deploy no other resources into it.&nbsp;<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture2_30.png\" alt=\"bastion pic 2\" \/><\/p>\n<p>&nbsp;6. Azure automatically assigns a Standard Public IP to the Bastion and generates a name based on the VNET. I decided to change mine, so it&#8217;s assigned to the Azure Bastion.&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture3_23.png\" alt=\"bastion pic 3\" \/><\/p>\n<p>7. Apply tags if required and then select <strong>Review + create<\/strong>&nbsp;and then <strong>Create<\/strong>. &nbsp;<\/p>\n<p>8. That&#8217;s it for the Bastion resource creation part. Grab yourself a quick beverage while&nbsp;the resources deploy, which usually takes no more than five minutes.&nbsp;&nbsp;<\/p>\n<p><strong>Configure Network Security Group (NSG) rules<\/strong><\/p>\n<p>Because the Bastion is a managed service, Microsoft hardens it by default. However, NSGs need to be applied to secure the subnet in which the Bastion host resides and apply the correct level of network access to the Bastion subnet as well as the subnets in which the target VMs reside so that the Bastion can connect to them successfully.<\/p>\n<p><strong>Create and configure NSG rules on AzureBastionSubnet<\/strong><\/p>\n<p>9. First, create the NSG that associates with AzureBastionSubnet. From the Azure home page,&nbsp;click on <strong>+ Create a resource<\/strong>.<br \/>\n10. Type <em>network security group<\/em>, and on the results page, you should see the Network&nbsp;security group icon (verify the publisher is Microsoft). Go ahead and click <strong>Create<\/strong>.<br \/>\n11. On the <strong>Create network security group<\/strong>&nbsp;page, create or choose an existing resource&nbsp;group, give the NSG a name, and select a region<br \/>\n12. Apply tags if required, select <strong>Review + create<\/strong>, and then click <strong>Create<\/strong>.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture4_20.png\" alt=\"bastion pic 4\" \/><\/p>\n<p>13. After you create the NSG, navigate to it and create the appropriate <strong>inbound<\/strong>&nbsp;rules. Click <strong>Inbound security rules<\/strong>&nbsp;under <strong>Settings<\/strong>. Notice three default rules from&nbsp;priority 65000-65500. You cannot delete these, but you can override them with rules that have a higher priority. Click <strong>+Add<\/strong>&nbsp;and create the following rules for paying attention to the priority numbers:<\/p>\n<ul>\n<li><strong>AllowHttpsInbound<\/strong>: The Bastion public IP needs port 443 enabled for inbound traffic when you connect to it.<\/li>\n<li><strong>AllowGatewayManagerInbound<\/strong>: For control plane connectivity, you enable port 443&nbsp;inbound from GatewayManager. This enables the control plane (which essentially is Gateway Manager) to communicate to the Azure Bastion.<\/li>\n<li><strong>AllowAzureLoadBalancerInbound<\/strong>: For health probes to work, you enable port 443&nbsp;inbound from the AzureLoadBalancer to allow Azure Load Balancer to detect connectivity.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture5_16.png\" alt=\"bastion pic 5\" \/><\/p>\n<p>14. Next, add the appropriate <strong>outbound<\/strong>&nbsp;rules. Click <strong>Outbound security rules<\/strong>&nbsp;under <strong>Settings<\/strong>. Notice three default rules from priority 65000-65500, and just like the Inbound default rules, you can&#8217;t delete these, but you can override them. Click <strong>+Add<\/strong>&nbsp;and create the following rules paying attention to the priority numbers:<\/p>\n<ul>\n<li><strong>AllowSshRdpOutbound<\/strong>: The Bastion reaches the target VMs (WindowsVM01 and LinuxVM01)&nbsp;over private IP, so this rule is in place to allow outbound traffic to the VM&#8217;s subnets on port 3389 and 22.<\/li>\n<li><strong>AllowAzureCloudOutbound<\/strong>: The Bastion needs to connect out to various public endpoints within Azure for things like writing data to Azure diagnostic logs, so this rule allows that access. &nbsp;<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture6_13.png\" alt=\"bastion pic 6 \" \/><\/p>\n<p><strong>Configure NSG rules on the target VM subnets&nbsp;<\/strong><\/p>\n<p>15. As a reminder, the target VMs&#8217; subnets are <strong>UKS-VNET01-SPOKE01-SN01<\/strong>&nbsp;(where WindowsVM01&nbsp;resides) and <strong>EUS-VNET01-SPOKE01-SN01<\/strong>&nbsp;(where LinuxVM01 resides). When I created the&nbsp;VMs, default NSGs already existed, and I reassigned them to the corresponding subnets. Now go to each subnet&#8217;s NSG and add the appropriate rule to each. I need to&nbsp;add only one <strong>inbound<\/strong>&nbsp;rule to each NSG as per the following:<\/p>\n<ul>\n<li><strong>AllowAzBastionSshRdpInbound<\/strong>: The Bastion reaches the target VMs over private IP&nbsp;using RDP\/SSH, so I need to open ports 3389 and 22 on the subnets in which the target VMs reside. As a best practice, I added the Bastion Subnet IP address range as the&nbsp;<strong>Source<\/strong>&nbsp;in this rule to allow only the Bastion to be able to open these ports on the target VM in each subnet.<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture7_8.png\" alt=\"bastion pic 7\" \/><\/p>\n<p><strong>Configure peering between the Hub VNET and Spoke VNETs&nbsp;<\/strong><\/p>\n<p>Now, we need to configure peering between the Hub VNET where the Azure Bastion resides to each of the Spoke VNETs where the target VMs reside so that traffic can flow.&nbsp;<br \/>\n&nbsp;<br \/>\n16. Start with peering the UKS-VNET02-HUB01 Hub VNET with UKS-VNET01-SPOKE01, where&nbsp;WindowsVM01 resides. Navigate to the <strong>UKS-VNET02-HUB01<\/strong>&nbsp;VNET, select <strong>Peerings&nbsp;<\/strong>under <strong>Settings<\/strong>, and click <strong>+Add<\/strong>.&nbsp;<br \/>\n17. On the <strong>Add Peering<\/strong>&nbsp;page, start with the <strong>This virtual network<\/strong>&nbsp;section, meaning<br \/>\n&nbsp; &nbsp; UKS-VNET02-HUB01 in this case, and make the following changes:<\/p>\n<ul>\n<li>&nbsp; &nbsp; <strong>Name<\/strong>: <em>`UKS-VNET02-HUB01-to-UKS-VNET01-SPOKE01`<\/em><\/li>\n<li>&nbsp; &nbsp; Allow Traffic to the remote virtual network.<\/li>\n<li>&nbsp; &nbsp; Block traffic that originates from outside this virtual network (I don&#8217;t need to allow traffic forwarding).<\/li>\n<li>&nbsp; &nbsp; Choose <strong>None<\/strong> for VNET Gateway.<\/li>\n<\/ul>\n<p>18. For the <strong>Remote virtual network<\/strong> section, meaning UKS-VNET01-SPOKE01 in this case,&nbsp;make the following changes:<\/p>\n<ul>\n<li>&nbsp; &nbsp; <strong>Name<\/strong>: <em>`UKS-VNET01-SPOKE01-to-UKS-VNET02-HUB01<\/em>`<\/li>\n<li>&nbsp; &nbsp; Select <strong>UKS-VNET01-SPOKE01&nbsp;<\/strong>from the Virtual network dropdown.<\/li>\n<li>&nbsp; &nbsp; Allow Traffic to the remote virtual network.<\/li>\n<li>&nbsp; &nbsp; Block traffic that originates from outside this virtual network ( don&#8217;t need to allow traffic forwarding).<\/li>\n<li>&nbsp; &nbsp; Choose <strong>None<\/strong> for VNET Gateway.<\/li>\n<\/ul>\n<p>19. After you click <strong>Add<\/strong>, Azure begins configuring peering connections on both of the VNETs, and you see a status like the following:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture8_7.png\" alt=\"bastion pic 8\" \/><\/p>\n<p>20. After it completes, you can verify that the peering connection exists by checking that&nbsp;the <strong>Peering<\/strong>&nbsp;status is <em>Connected<\/em>&nbsp;for the peerings on both the VNETs.<br \/>\n&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture9_7.png\" alt=\"bastion pic 9\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture10_4.png\" alt=\"bastion pic 10\" \/><\/p>\n<p>&nbsp;<br \/>\n21. I followed the same process used in steps 16-20 to configure peering between&nbsp;UKS-VNET02-HUB01 and the second spoke VNET EUS-VNET01-SPOKE01 where LinuxVM01 resides, but simply changed the peering names accordingly.&nbsp;<\/p>\n<p><strong>Connect to the target VMs<\/strong><\/p>\n<p>If you set up everything correctly, then you should now be able to connect to each VM by using the Bastion successfully. Let&#8217;s give it a go!<br \/>\n&nbsp;<\/p>\n<p>22.Start with WindowsVM01, which resides in a spoke VNET in the same region (UK South)&nbsp;as the Hub VNET. I navigate to the VM resource and click on Connect and choose <strong>Bastion<\/strong>&nbsp;from the dropdown menu.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture11_3.png\" alt=\"bastion pic 11\" \/><\/p>\n<p>&nbsp;<br \/>\n23. Select <strong>Use Bastion<\/strong>&nbsp;and enter the username and password. Click <strong>Connect<\/strong>.<br \/>\n&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture12_3.png\" alt=\"bastion pic 12\" \/><\/p>\n<p>&nbsp;<br \/>\n24. The RDP connection to WindowsVM01 through the Bastion opens in a separate browser tab using port 443.<br \/>\n&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture13_1.png\" alt=\"bastion pic 13\" \/><\/p>\n<p>25. Now, connect to LinuxVM01, which resides in a spoke VNET in a different region (East US) to the Hub VNET. Navigate to the VM and select <strong>Bastion<\/strong>&nbsp;as the connection&nbsp;method, just like was done for WindowsVM01.&nbsp;<br \/>\n26. Enter admin login credentials and click <strong>Connect<\/strong>. A username\/password is required&nbsp;combination for this demo, but for a production setup, it&#8217;s wise to use SSH keys.<br \/>\n&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture14_1.png\" alt=\"bastion pic 14\" \/><\/p>\n<p>&nbsp;<br \/>\n27. The SSH connection to LinuxVM01 via the Bastion opens in a separate browser tab using&nbsp;port 443.<br \/>\n&nbsp;<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26425-body-Picture15_0.png\" alt=\"bastion pic 15\" \/><\/p>\n<p><strong>&nbsp;Conclusion<\/strong><\/p>\n<p>This post provides steps on implementing Azure Bastion in a hub-and-spoke topology model by using VNET peering and connecting to target VMs. This setup type allows you to centralize the Bastion host and simplify your remote management solution for server administration activities.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Implement Azure Bastion with VNET peering<\/p>\n","protected":false},"author":2,"featured_media":7493,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","format":"standard","meta":{"content-type":"","nid":"26425","content_type":"blog","created_by":"10130","authored_on":"2023-12-31T17:14:59+00:00","field_article_industries":"","tag_category":"Technical","field_blog_author_text":"by Hitesh Vadgama, Solutions Architect, Rackspace Technology","seo_description":"Prepare for cloud migration with operational readiness checklist. Ensure optimal service performance and risk management.\r\n","field_featured_image":"","insights_image":"\/wp-content\/uploads\/2026\/blog_technical_images\/26425-insights_image-microsoft-technical-blog-1-insights.jpg","field_partners":"","rxt_platforms":"Microsoft Azure","product":"","publisheddate":"2020-12-11T17:14:59","rxt_solutions":"Cloud Management & Operations, Multicloud, Public Cloud","opengraph_tag":"","x_tag":"","teaser_flag":"Technical Blog","seo_titile":"Azure Bastion VNET peering | Rackspace Technology","field_topics":"","field_slug":"implement-azure-bastion-with-vnet-peering","footnotes":""},"categories":[178],"tags":[204],"class_list":["post-7491","blogs","type-blogs","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-technical"],"_links":{"self":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7491","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs"}],"about":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/types\/blogs"}],"author":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/comments?post=7491"}],"version-history":[{"count":3,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7491\/revisions"}],"predecessor-version":[{"id":9504,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7491\/revisions\/9504"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/media\/7493"}],"wp:attachment":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/media?parent=7491"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/categories?post=7491"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/tags?post=7491"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}