0
0
Azurecloud~5 mins

Azure Bastion for secure VM access - Commands & Configuration

Choose your learning style9 modes available
Introduction
Accessing virtual machines securely over the internet can be risky. Azure Bastion provides a safe way to connect to your VMs without exposing them directly to the internet.
When you want to connect to a VM without opening public ports like RDP or SSH.
When you need to securely manage VMs from the Azure portal using a browser.
When you want to reduce the risk of attacks by avoiding exposing VM IP addresses.
When you want to simplify network security by not managing jump servers or VPNs.
When you want encrypted and seamless VM access without extra client software.
Config File - azuredeploy.json
azuredeploy.json
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "bastionName": {
      "type": "string",
      "defaultValue": "myBastionHost"
    },
    "virtualNetworkName": {
      "type": "string",
      "defaultValue": "myVnet"
    },
    "subnetName": {
      "type": "string",
      "defaultValue": "AzureBastionSubnet"
    },
    "location": {
      "type": "string",
      "defaultValue": "eastus"
    },
    "publicIpName": {
      "type": "string",
      "defaultValue": "myBastionPublicIP"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2021-05-01",
      "name": "[parameters('publicIpName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard"
      },
      "properties": {
        "publicIPAllocationMethod": "Static"
      }
    },
    {
      "type": "Microsoft.Network/bastionHosts",
      "apiVersion": "2021-05-01",
      "name": "[parameters('bastionName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "bastionIPConfig",
            "properties": {
              "subnet": {
                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]"
              },
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpName'))]"
              }
            }
          }
        ]
      }
    }
  ]
}

This ARM template creates a public IP address with a static allocation and the Standard SKU, which is required for Azure Bastion. It then creates the Azure Bastion host resource linked to the specified virtual network and subnet named AzureBastionSubnet. The subnet name AzureBastionSubnet is mandatory for Bastion. The Bastion host allows secure RDP/SSH access to VMs inside the virtual network without exposing them publicly.

Commands
Create the required subnet named AzureBastionSubnet in the virtual network. This subnet is reserved for Azure Bastion and must be named exactly this.
Terminal
az network vnet subnet create --resource-group myResourceGroup --vnet-name myVnet --name AzureBastionSubnet --address-prefixes 10.0.1.0/27
Expected OutputExpected
{ "addressPrefix": "10.0.1.0/27", "addressPrefixes": [ "10.0.1.0/27" ], "delegations": [], "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/AzureBastionSubnet", "name": "AzureBastionSubnet", "privateEndpointNetworkPolicies": "Enabled", "privateLinkServiceNetworkPolicies": "Enabled", "provisioningState": "Succeeded", "resourceGroup": "myResourceGroup", "resourceNavigationLinks": [], "routeTable": null, "serviceEndpoints": [], "type": "Microsoft.Network/virtualNetworks/subnets" }
--resource-group - Specifies the resource group where the subnet is created
--vnet-name - Specifies the virtual network name
--name - Subnet name, must be AzureBastionSubnet for Bastion
Create a static public IP address with Standard SKU for the Bastion host. This IP is used to connect securely to the VMs.
Terminal
az network public-ip create --resource-group myResourceGroup --name myBastionPublicIP --sku Standard --location eastus --allocation-method Static
Expected OutputExpected
{ "dnsSettings": null, "etag": "W/\"00000000-0000-0000-0000-000000000000\"", "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/publicIPAddresses/myBastionPublicIP", "ipAddress": "52.170.12.34", "ipTags": [], "location": "eastus", "name": "myBastionPublicIP", "provisioningState": "Succeeded", "publicIPAllocationMethod": "Static", "publicIPAddressVersion": "IPv4", "resourceGroup": "myResourceGroup", "sku": { "name": "Standard" }, "tags": {}, "type": "Microsoft.Network/publicIPAddresses" }
--sku - Must be Standard for Azure Bastion
--allocation-method - Static IP allocation is required
Create the Azure Bastion host resource linked to the virtual network and public IP. This enables secure VM access.
Terminal
az network bastion create --resource-group myResourceGroup --name myBastionHost --public-ip-address myBastionPublicIP --vnet-name myVnet --location eastus
Expected OutputExpected
{ "etag": "W/\"00000000-0000-0000-0000-000000000000\"", "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/bastionHosts/myBastionHost", "location": "eastus", "name": "myBastionHost", "provisioningState": "Succeeded", "resourceGroup": "myResourceGroup", "tags": {}, "type": "Microsoft.Network/bastionHosts" }
--public-ip-address - Associates the Bastion with the public IP
--vnet-name - Specifies the virtual network where Bastion is deployed
Verify the Bastion host was created successfully and check its details.
Terminal
az network bastion show --resource-group myResourceGroup --name myBastionHost
Expected OutputExpected
{ "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Network/bastionHosts/myBastionHost", "location": "eastus", "name": "myBastionHost", "provisioningState": "Succeeded", "resourceGroup": "myResourceGroup", "type": "Microsoft.Network/bastionHosts" }
Key Concept

If you remember nothing else from this pattern, remember: Azure Bastion lets you securely connect to VMs without exposing them to the internet by using a special subnet and public IP.

Common Mistakes
Naming the subnet anything other than AzureBastionSubnet
Azure Bastion requires the subnet to be named exactly AzureBastionSubnet to function properly.
Always create a subnet named AzureBastionSubnet in your virtual network before deploying Bastion.
Using a Basic SKU public IP instead of Standard
Azure Bastion requires a Standard SKU public IP for proper functionality and SLA.
Create the public IP with --sku Standard and --allocation-method Static.
Not associating the Bastion host with the correct virtual network or public IP
Bastion won't work if it is not linked to the right virtual network and public IP address.
Specify the correct --vnet-name and --public-ip-address when creating the Bastion host.
Summary
Create a subnet named AzureBastionSubnet in your virtual network for Bastion.
Create a static Standard SKU public IP address for the Bastion host.
Deploy the Azure Bastion host linked to the subnet and public IP.
Verify the Bastion host is deployed successfully before connecting to VMs.