Azure Centralized Bastion Solution
Follow up on my blogs regarding Azure AD (Microsoft Entra ID) login to Azure Virtual Machines
- Login to a Virtual Machine using Azure AD Account on Linux
- [Terraform] Deploy Azure Virtual Machine with AAD enabled
- AzureAD support for Azure VMSS (virtual machine scale set)
- Azure Centralized Bastion Solution
- Configure Local Group Policy to Disable NLA in Windows Server 2019 for AzureAD-Ready Logins.
Background
- To enable Azure AD login support, the Azure Bastion needs to be in the Standard tier. Opting for a centralized bastion solution could result in substantial savings, approximately $200 plus support and GST per subscription per month. Given that my company manages around 100 Azure subscriptions, this approach has the potential to save a total of approximately $20,000 per month if the solution performs as expected.

- Additionally, adopting a centralized bastion solution eliminates the need for a
/26 IP spacein each spoke subscription, as the subnet AzureBastionSubnet is no longer required in the Spoke VNET. - It’s crucial to note that Azure Bastion within a Virtual WAN hub is currently not supported.

- Another noteworthy discovery is that multiple bastion hosts in same VNet are not permitted in Azure.

- security complaince — we need to ensure that there is compliance with security standards.
Design
- Need setup VNET peering (one-way only) on all spoke VNETs to Hub VNET
- Only one Bastion need be created. If you have bastion created in spoke Vnet, you need delete them

Verify permissions
Verify the following permissions when working with this architecture:
- Ensure you have read access to both the target VM and the peered VNet.
- Check your permissions in YourSubscription | IAM and verify that you have read access to the following resources:
- Reader role on the virtual machine.
- Reader role on the NIC with private IP of the virtual machine.
- Reader role on the Azure Bastion resource.
- Reader role on the virtual networks of the target virtual machines.
Setup
- Delete existing Azure Bastion Service in spoke Vnet
- Delete subnet
AzureBastionSubnetin spoke Vnet - (optional) Setup Virtual Machines access with AzureAD accounts. one is linux and the other is Windows system
- Choice one Vnet as Hub Vnet, in this sample, we choice
central-nonprodas the hub vnet - Create a Vnet peering (single way is enough) from
central-nonprodsubscription to all spoke Vnet

Test #1 — Linux VM
VM: created on dev01-nonprod
Bastion: created in central-nonprod
You can login as normal from Azure Portal with local account
You can’t login from Azure Portal with AAD for linux VM. So you need run Azure CLI to login Linux with AAD (Microsoft Entra ID) account.
$ cat dev01-linux.sh
subscription=dev01-nonprod
az account set -s ${subscription}
az account show
bastionName="central-nonprod-VNET-bastion"
bastionRG="vnet-RG"
bastionSubID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
vmName="test-linux-rhel9"
vmRG="test-linux-rhel9-rg"
vmId=$(az vm list --resource-group ${vmRG} --query "[?name=='$vmName'].id" --output tsv)
echo $vmId
az network bastion ssh --name "${bastionName}" --resource-group "${bastionRG}" --subscription ${bastionSubID} --target-resource-id "${vmId}" --auth-type AAD
$ ./cat dev01-linux.shTest #2 — Windows VM
VM: created on dev01-nonprod
Bastion: created in central-nonprod
- (optional) Enable AAD on the windows VM following Azure official document
- If login as AAD, login username would be
AzureAD/<your_mailbox>
When you login the windows VM by Bastion, it will automatically choice the bastion from subscription central-nonprod
Extra test reports with summary
- I can login a Linux VM (created in dev01) from Bastion (in
central-nonprod) with AAD by vpc peering enabled. - Need login via Azure CLI command. - It is fine to login with local account - It is fine to login with AAD account - Got similar result with Windows VM - it is fine to login with local account - it is fine to login with AAD as well - copy & paste text is fine - can’t copy & paste fiiles - need login with browser incognito mode
Bastion with IP-based connection
The business is not in favor of the Bastion IP-Based connection solution. This is primarily due to the requirement for all end users to log in to VMs exclusively from the central-nonprod subscription. Additionally, the IP-Based connection necessitates a Virtual Hub network, and while our environment has set up a virtual hub, obtaining VM IPs is often challenging and inconvenient. Furthermore, the IP-Based connection lacks support for logging in with DNS names or VM names.
As a result, we have decided to abandon this design.
But I still run the tests and report here.
- I can login Window VM with AAD by its IP address, but end users need subscription permission to login VM in
central-nonprod - I can’t login Windows VM by normal way, such as, directly login via Azure Portal in VM’s subscription.
- I can login Linux VM with AAD by its IP address by azure command line
- I can login Linux VM with AAD by its ID (name) by azure command line
- I can’t login with hostname or private DNS name by IP-Based connection
Reference
https://learn.microsoft.com/en-us/azure/bastion/vnet-peering
https://learn.microsoft.com/en-us/azure/virtual-network/tutorial-connect-virtual-networks-portal
