Bastion Host
Introduction
Section titled “Introduction”Azure Bastion Host provides secure and seamless RDP and SSH connectivity to virtual machines directly through the Azure portal over TLS. Bastion is deployed in a virtual network and eliminates the need for a public IP address on the VM, protecting against port scanning and other external threats. It is the recommended approach for securely accessing Azure VMs without exposing them to the public internet. For more information, see What is Azure Bastion?.
LocalStack for Azure provides a local environment for building and testing applications that make use of Bastion Host. The supported APIs are available on our API Coverage section, which provides information on the extent of Bastion Host’s integration with LocalStack.
Getting started
Section titled “Getting started”This guide is designed for users new to Bastion Host and assumes basic knowledge of the Azure CLI and our azlocal wrapper script.
Launch LocalStack using your preferred method. For more information, see Introduction to LocalStack for Azure. Once the container is running, enable Azure CLI interception by running:
azlocal start-interceptionThis command points the az CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API.
To revert this configuration, run:
azlocal stop-interceptionThis reconfigures the az CLI to send commands to the official Azure management REST API.
Create a resource group and virtual network
Section titled “Create a resource group and virtual network”Bastion Host requires a subnet named exactly AzureBastionSubnet and a Standard SKU public IP address. Create the prerequisites first:
az group create \ --name rg-bastion-demo \ --location westeurope{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo", "location": "westeurope", "managedBy": null, "name": "rg-bastion-demo", "properties": { "provisioningState": "Succeeded" }, "tags": null, "type": "Microsoft.Resources/resourceGroups"}Create a virtual network with a /16 address space to host the bastion subnet:
az network vnet create \ --name vnet-bastion-demo \ --resource-group rg-bastion-demo \ --location westeurope \ --address-prefixes 10.0.0.0/16{ "newVNet": { "addressSpace": { "addressPrefixes": [ "10.0.0.0/16" ] }, "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/virtualNetworks/vnet-bastion-demo", "location": "westeurope", "name": "vnet-bastion-demo", "provisioningState": "Succeeded", "resourceGroup": "rg-bastion-demo", "subnets": [], "type": "Microsoft.Network/virtualNetworks", ... }}Create the AzureBastionSubnet subnet, which is required by Azure Bastion:
az network vnet subnet create \ --name AzureBastionSubnet \ --resource-group rg-bastion-demo \ --vnet-name vnet-bastion-demo \ --address-prefixes 10.0.255.0/27{ "addressPrefix": "10.0.255.0/27", "delegations": [], "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/virtualNetworks/vnet-bastion-demo/subnets/AzureBastionSubnet", "name": "AzureBastionSubnet", "privateEndpointNetworkPolicies": "Disabled", "privateLinkServiceNetworkPolicies": "Enabled", "provisioningState": "Succeeded", "resourceGroup": "rg-bastion-demo", "type": "Microsoft.Network/virtualNetworks/subnets"...}Create a Standard public IP address
Section titled “Create a Standard public IP address”Create a Standard SKU static public IP address required by the Bastion host:
az network public-ip create \ --name pip-bastion \ --resource-group rg-bastion-demo \ --location westeurope \ --sku Standard \ --allocation-method Static{ "publicIp": { "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/publicIPAddresses/pip-bastion", "idleTimeoutInMinutes": 4, "ipAddress": "20.56.137.218", "location": "westeurope", "name": "pip-bastion", "provisioningState": "Succeeded", "publicIPAllocationMethod": "Static", "resourceGroup": "rg-bastion-demo", "sku": { "name": "Standard", "tier": "Regional" }, "type": "Microsoft.Network/publicIPAddresses", ... }}Create a bastion host
Section titled “Create a bastion host”Create the Bastion host, linking it to the virtual network and the public IP address:
az network bastion create \ --name bastion-demo \ --resource-group rg-bastion-demo \ --location westeurope \ --vnet-name vnet-bastion-demo \ --public-ip-address pip-bastion{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/bastionHosts/bastion-demo", "ipConfigurations": [ { "name": "bastion_ip_config", "provisioningState": "Succeeded", "publicIPAddress": { "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/publicIPAddresses/pip-bastion", "resourceGroup": "rg-bastion-demo" }, "subnet": { "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/virtualNetworks/vnet-bastion-demo/subnets/AzureBastionSubnet", "resourceGroup": "rg-bastion-demo" } } ], "location": "westeurope", "name": "bastion-demo", "provisioningState": "Succeeded", "resourceGroup": "rg-bastion-demo", "scaleUnits": 2, "sku": { "name": "Standard" }, "zones": []}Get and list bastion hosts
Section titled “Get and list bastion hosts”Retrieve the details of the Bastion host and list all Bastion instances in the resource group:
az network bastion show \ --name bastion-demo \ --resource-group rg-bastion-demo{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/bastionHosts/bastion-demo", "ipConfigurations": [ { "name": "bastion_ip_config", "provisioningState": "Succeeded", "publicIPAddress": { "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/publicIPAddresses/pip-bastion", "resourceGroup": "rg-bastion-demo" }, "subnet": { "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/virtualNetworks/vnet-bastion-demo/subnets/AzureBastionSubnet", "resourceGroup": "rg-bastion-demo" } } ], "location": "westeurope", "name": "bastion-demo", "provisioningState": "Succeeded", "resourceGroup": "rg-bastion-demo", "scaleUnits": 2, "sku": { "name": "Standard" }, "zones": []}Then list all Bastion instances in the resource group:
az network bastion list --resource-group rg-bastion-demo[ { "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-bastion-demo/providers/Microsoft.Network/bastionHosts/bastion-demo", "ipConfigurations": [ { "name": "bastion_ip_config", "provisioningState": "Succeeded", "publicIPAddress": { "id": "...pip-bastion...", "resourceGroup": "rg-bastion-demo" }, "subnet": { "id": "...AzureBastionSubnet...", "resourceGroup": "rg-bastion-demo" } } ], "location": "westeurope", "name": "bastion-demo", "provisioningState": "Succeeded", "resourceGroup": "rg-bastion-demo", "scaleUnits": 2, "sku": { "name": "Standard" }, "zones": [] }]Delete the bastion host
Section titled “Delete the bastion host”Delete the Bastion host and verify it no longer appears in the list:
az network bastion delete \ --name bastion-demo \ --resource-group rg-bastion-demo \ --yesThen list all bastion hosts to confirm the resource group is now empty:
az network bastion list --resource-group rg-bastion-demo[]Features
Section titled “Features”The Bastion Host emulator supports the following features:
- Create and manage bastion hosts: Full lifecycle management including create, get, update, list, and delete.
- Subnet name validation: Enforces that the target subnet is named
AzureBastionSubnet, matching Azure’s requirement. - Standard SKU public IP validation: Enforces that the associated public IP address uses the Standard SKU and Static allocation.
- IP configuration storage: Records and returns the subnet and public IP address associations in
ipConfigurations. - Tags: Apply and update resource tags on bastion host resources.
- SKU tiers: Support for
BasicandStandardbastion SKUs.
Limitations
Section titled “Limitations”- No RDP or SSH connectivity: Bastion Host is a mock implementation. No actual remote desktop or SSH sessions are established through the emulator.
- No TLS tunnel: The secure TLS tunneling behavior of Azure Bastion is not simulated.
- No VM connectivity verification: The emulator does not verify that the target VM exists or is reachable.
- No data persistence: Bastion Host resources are not persisted and are lost when the emulator is stopped or restarted.
Samples
Section titled “Samples”Explore end-to-end examples in the LocalStack for Azure Samples repository.
API Coverage
Section titled “API Coverage”| Operation ▲ | Implemented ▼ |
|---|