Azure Bastion has four SKUs. Developer is free and connects to one VM at a time in the same virtual network, Basic gives you a dedicated two-instance host with peering support, Standard adds the native client, IP-based connections, shareable links, custom ports and host scaling up to 50 instances, and Premium adds session recording and a private-only deployment with no public IP. For production, pick Standard or Premium unless Basic's fixed capacity and browser-only access are enough, and remember you can upgrade later but never downgrade.
Who this is for and what you will have
This guide is for administrators who want to remove public IP addresses and open RDP or SSH ports from their virtual machines and need to decide which Bastion tier to pay for. At the end you will have:
- A clear mapping of features and limits to each SKU.
- A deployed bastion host with the subnet, public IP and network security group rules it needs.
- Working browser and native client connections to Windows and Linux VMs.
- An upgrade path and a troubleshooting checklist.
Bastion is usually one part of a broader remote access design; the zero trust remote access architecture post places it alongside VPN and identity-aware access.
Feature comparison
The table summarises Microsoft's SKU comparison.
| Feature | Developer | Basic | Standard | Premium |
|---|---|---|---|---|
| Requires AzureBastionSubnet | No | Yes | Yes | Yes |
| Requires public IP address | No | Yes | Yes | No (private-only option) |
| Dedicated bastion host | No | Yes | Yes | Yes |
| Virtual network peering | No | Yes | Yes | Yes |
| Concurrent connections | No | Yes | Yes | Yes |
| RDP to Windows, SSH to Linux | Yes | Yes | Yes | Yes |
| RDP to Linux, SSH to Windows | No | No | Yes | Yes |
| Kerberos authentication | Yes | Yes | Yes | Yes |
| Linux private keys from Azure Key Vault | Yes | Yes | Yes | Yes |
| Native client (Azure CLI) | No | No | Yes | Yes |
| Custom inbound port | No | No | Yes | Yes |
| IP-based connection | No | No | Yes | Yes |
| Shareable link | No | No | Yes | Yes |
| File upload and download (native client) | No | No | Yes | Yes |
| Disable copy and paste | No | No | Yes | Yes |
| Session recording | No | No | No | Yes |
| Private-only deployment | No | No | No | Yes |
| Hourly charge | Free | Paid | Paid | Paid |
Every dedicated SKU is billed per hour from the moment it's deployed, whether or not anyone connects, plus outbound data transfer; Microsoft states the first 5 GB per month of outbound data is free. Check the Azure Bastion pricing page for current rates in your region rather than relying on figures quoted elsewhere.
Capacity and scaling
| Metric | Developer | Basic | Standard | Premium |
|---|---|---|---|---|
| Deployment model | Shared | Dedicated | Dedicated | Dedicated |
| Instances | Shared pool | 2 (fixed) | 2 to 50 | 2 to 50 |
| Per-instance capacity | Not applicable | 20 RDP and 40 SSH | 20 RDP and 40 SSH | 20 RDP and 40 SSH |
| Maximum RDP sessions | 1 | 40 | 1,000 | 1,000 |
| Maximum SSH sessions | 1 | 80 | 2,000 | 2,000 |
An instance, or scale unit, is a Microsoft-managed VM behind your bastion host. On Standard and Premium you set the instance count yourself; this is called host scaling. A /26 AzureBastionSubnet is the minimum for new deployments, and Microsoft recommends /26 or larger for host scaling because a smaller subnet limits the number of scale units. Older /27 subnets keep working, but Microsoft recommends growing them to /26.
Which SKU to choose
- Developer for personal dev and test VMs in a supported region, when one connection at a time is fine and the VM is in the same virtual network. Microsoft explicitly says it isn't suitable for production.
- Basic for a small production estate that only needs browser access through the Azure portal and fits in 40 RDP or 80 SSH sessions.
- Standard when administrators want their own RDP and SSH clients, file transfer, custom ports, shareable links for people without portal access, IP-based connections to VMs by private IP address, or more capacity.
- Premium when you need session recording for audit, or a private-only host reachable only over ExpressRoute or VPN. Microsoft's own guidance says the cost difference between Standard and Premium is marginal and recommends Premium for production.
In a hub-and-spoke network, one Basic or higher host in the hub can reach VMs in peered spokes, including peered virtual networks in other subscriptions of the same tenant. The hub-and-spoke network with Azure Firewall post shows where it fits.
Prerequisites
- Roles for users who connect: Reader on the VM, Reader on the VM's network interface, Reader on the bastion resource, and Reader on the target VM's virtual network when Bastion is in a peered network. Windows users also need to be local administrators or members of Remote Desktop Users on the VM.
- Permissions to deploy:
Microsoft.Network/virtualNetworks/write,Microsoft.Network/virtualNetworks/subnets/join/actionandMicrosoft.Network/publicIPAddresses. - AzureBastionSubnet for dedicated SKUs: named exactly
AzureBastionSubnet, /26 or larger, in the same virtual network and resource group as the bastion host, and containing nothing else. - Public IP address for dedicated SKUs other than private-only Premium: Standard SKU with static allocation.
- VM ports: 3389 for Windows and 22 for Linux, or your custom port on Standard and Premium. VMs don't need a public IP, an agent or client software.
Deploy Bastion Developer
Open the virtual network in a region that supports Developer, select Connect > Bastion, choose an Authentication Type, enter credentials and select Connect. Bastion Developer deploys in seconds, opens the session in the portal and stays deployed for later connections. With the Azure CLI:
az network bastion create --name bas-dev --resource-group rg-dev \
--vnet-name vnet-dev --sku DeveloperThe CLI also accepts network ACL IP rules for a Developer host through --network-acls-ips, a parameter supported only on the Developer SKU.
Deploy a dedicated SKU
In the portal, open the virtual network, select Connect > Bastion and choose Configure manually (the one-click Deploy Bastion option uses the Standard SKU with default settings). Set:
- Tier: Basic, Standard or Premium
- Instance count: 2 or more on Standard and Premium
- Availability zone: choose zones now if the region supports them; you can't change zone settings after deployment
- Subnet: use Edit subnet, set Subnet purpose to Azure Bastion and a /26 or larger range
- Public IPv4 address: create a new one or select an unused existing Standard static address
- Advanced tab: Native Client Support, IP-based connection, Shareable Link, Session recording and other options, depending on the tier
Dedicated deployments take about 10 minutes. The equivalent Azure CLI, with native client and IP-based connections enabled:
az network vnet subnet create --resource-group rg-hub --vnet-name vnet-hub \
--name AzureBastionSubnet --address-prefixes 10.100.1.0/26
az network public-ip create --resource-group rg-hub --name pip-bastion \
--sku Standard --allocation-method Static
az network bastion create --name bas-hub --resource-group rg-hub \
--vnet-name vnet-hub --public-ip-address pip-bastion --location westeurope \
--sku Standard --scale-units 2 --enable-tunneling true --enable-ip-connect trueNote the defaults: az network bastion create uses Standard if you omit --sku, while the PowerShell cmdlet New-AzBastion defaults to Basic. Always set the SKU explicitly.
Apply network security group rules
NSGs are supported on AzureBastionSubnet, but if you add one you must create every rule Microsoft lists. Missing rules stop the host receiving platform updates and can break connectivity.
| Rule | Direction | Source | Destination | Ports |
|---|---|---|---|---|
| AllowHttpsInbound | Inbound | Internet (or your public ranges) | Any | 443 TCP |
| AllowGatewayManagerInbound | Inbound | GatewayManager | Any | 443 TCP |
| AllowAzureLoadBalancerInbound | Inbound | AzureLoadBalancer | Any | 443 TCP |
| AllowBastionHostCommunication | Inbound | VirtualNetwork | VirtualNetwork | 8080, 5701 |
| AllowSshRdpOutbound | Outbound | Any | VirtualNetwork | 22, 3389 |
| AllowAzureCloudOutbound | Outbound | Any | AzureCloud | 443 TCP |
| AllowBastionCommunication | Outbound | VirtualNetwork | VirtualNetwork | 8080, 5701 |
| AllowHttpOutbound | Outbound | Any | Internet | 80 |
Ports 3389 and 22 aren't needed inbound on AzureBastionSubnet. On the target VM subnets, allow 3389 and 22 (or your custom ports) inbound, ideally with the AzureBastionSubnet range as the only source. If you use custom ports, allow outbound from Bastion to the VirtualNetwork service tag instead of fixed ports.
Connect to virtual machines
From the portal, open the VM, select Connect > Bastion, choose the authentication type and connect; the session opens in the browser. Microsoft Entra ID sign-in works for SSH in the portal but not yet for RDP in the portal.
On Standard and Premium with Native Client Support enabled, use a current Azure CLI with the bastion extension, which installs automatically on first use and requires Azure CLI 2.62.0 or later. Get the VM's resource ID from its JSON View, then:
# RDP to a Windows VM with mstsc (from a Windows client)
az network bastion rdp --name bas-hub --resource-group rg-hub \
--target-resource-id "<vm-resource-id>"
# SSH to a Linux VM with Entra ID sign-in
az network bastion ssh --name bas-hub --resource-group rg-hub \
--target-resource-id "<vm-resource-id>" --auth-type AAD
# Tunnel for any client, for example OpenSSH from macOS or Linux
az network bastion tunnel --name bas-hub --resource-group rg-hub \
--target-resource-id "<vm-resource-id>" --resource-port 22 --port 50022
ssh azureuser@127.0.0.1 -p 50022az network bastion rdp accepts --enable-mfa for Entra ID-joined Windows targets (Windows 10 20H2 and later, Windows 11 21H2 and later, Windows Server 2022). RDP to an Entra ID-joined VM is only allowed from a Windows PC that is registered, joined or hybrid joined to the same directory. Replace --target-resource-id with --target-ip-address for IP-based connections, which don't support Entra ID sign-in or custom ports. The native client can't use SSH keys stored in Key Vault, doesn't run in Cloud Shell, and session recording doesn't cover native client sessions.
Deploy a private-only Premium host
Private-only Bastion has no public endpoint; users reach its private IP over ExpressRoute private peering or VPN. It must be chosen at deployment and requires Premium. You can't convert an existing deployment: delete the existing host first, then redeploy (the subnet can stay). In Configure manually, choose Premium, set Configure IP address to Private IP address, and on Advanced select IP-based connection for clients coming from on-premises. Use the native client for end-to-end private connectivity, and make sure NSGs don't block inbound 443 from the virtual network to AzureBastionSubnet.
Upgrade a SKU
Open the bastion host, select Configuration, choose a higher Tier, enable any new features and select Apply. Upgrades take about 10 minutes and existing sessions may drop briefly. Moving from Developer to a dedicated SKU also needs AzureBastionSubnet and a Standard static public IP (unless you go to private-only Premium). The CLI can upgrade Basic or Standard in place, but for Developer you delete the host and create it again:
az network bastion update --name bas-hub --resource-group rg-hub \
--location westeurope --sku name=Premium
az network bastion show --name bas-hub --resource-group rg-hub \
--query "{Name:name, SKU:sku.name, ProvisioningState:provisioningState}" --output tableInclude --location with az network bastion update; without it the CLI can pick a different region and fail with InvalidResourceLocation.
Verification
az network bastion showreports the SKU you expect andSucceeded.- A portal connection and, on Standard or Premium, a native client connection both reach a VM without a public IP.
- After confirming access, dissociate and delete any public IPs left on the VMs.
- For Premium with recording, a closed session appears on the Session Recording page.
Troubleshooting
Black screen in the portal session. Either the client network blocks WebSockets traffic to Bastion, or an NSG on AzureBastionSubnet or the VM subnet blocks the RDP or SSH path. Allow WebSockets on the client firewall and review both NSGs.
Unable to connect, no specific error. Use Connection Troubleshoot under Help on the bastion resource to test TCP reachability from a source to the VM. If just-in-time VM access is enabled, users also need Microsoft.Security/locations/jitNetworkAccessPolicies/read and .../write.
"Your session has expired." You opened the session URL directly in another tab or browser. Start the session again from the Azure portal.
Bastion breaks after on-premises connectivity changes. A default route (0.0.0.0/0) advertised over ExpressRoute or VPN into the virtual network breaks Bastion. User-defined routes aren't supported on AzureBastionSubnet, and Microsoft notes you don't need to send Bastion traffic through Azure Firewall, because Bastion-to-VM traffic stays private.
Bastion stops working after linking private DNS zones. Don't link the Bastion virtual network to private DNS zones named exactly management.azure.com, blob.core.windows.net, core.windows.net, vaultcore.windows.net, vault.azure.net or azure.com. Zones such as privatelink.blob.core.windows.net are fine.
Sessions drop during maintenance. Microsoft states existing sessions disconnect during maintenance on the bastion resource. Users reconnect afterwards.
Feature missing in the portal. The tier doesn't include it. Check the comparison table, then upgrade.
Closing checklist
- SKU chosen from features and session count, not just price; Premium if you need recording or private-only access.
- AzureBastionSubnet /26 or larger with no other resources and no route table.
- Standard static public IP, or private-only Premium over ExpressRoute or VPN.
- Complete NSG rule set on AzureBastionSubnet and Bastion-only RDP and SSH rules on VM subnets.
- Reader roles assigned on VM, NIC, bastion and peered virtual network.
- Native client enabled and tested on Standard or Premium.
- Public IPs removed from VMs once Bastion access is confirmed.
References
- Choose the right Azure Bastion SKU
- About Azure Bastion configuration settings
- Quickstart: Deploy Azure Bastion from the Azure portal
- Configure NSG rules for Azure Bastion
- Configure Bastion for native client connections
- Connect to a VM using Bastion and the Windows native client
- Deploy private-only Bastion
- View or upgrade an Azure Bastion SKU
- az network bastion
- New-AzBastion
- Azure Bastion FAQ
- Troubleshoot Azure Bastion connectivity problems