๐Ÿ›ก๏ธ Azure Bastion Host Implementation Guide

๐Ÿ“‹ Overview

Azure Bastion is a fully managed platform-as-a-service (PaaS) that provides secure and seamless RDP/SSH connectivity to your virtual machines directly through the Azure portal over TLS. This eliminates the need for public IP addresses on your VMs while providing secure access.

๐Ÿ—๏ธ High-Level Architecture

graph TB User[๐Ÿ‘ค User] --> Portal[๐ŸŒ Azure Portal] Portal --> Bastion[๐Ÿ›ก๏ธ Azure Bastion] Bastion --> AzureSubnet[๐Ÿ“ฆ AzureBastionSubnet] AzureSubnet --> VM1[๐Ÿ’ป VM 1] AzureSubnet --> VM2[๐Ÿ’ป VM 2] AzureSubnet --> VM3[๐Ÿ’ป VM 3] subgraph VNet [Virtual Network] Bastion AzureSubnet VM1 VM2 VM3 end style Bastion fill:#0078d4,stroke:#fff,stroke-width:2px,color:#fff style AzureSubnet fill:#4a90e2,stroke:#fff,stroke-width:2px,color:#fff style VNet fill:#e6f3ff,stroke:#0078d4,stroke-width:2px

Architecture Explanation

This diagram shows the high-level architecture of Azure Bastion. Users connect through the Azure Portal, which communicates with the Azure Bastion service. The Bastion service is deployed in a dedicated subnet called "AzureBastionSubnet" and provides secure connectivity to VMs within the same virtual network. The key benefit is that VMs don't need public IP addresses - all traffic flows through the secure Bastion tunnel.

๐Ÿ”„ Traffic Flow Diagram

sequenceDiagram participant U as ๐Ÿ‘ค User Browser participant AP as ๐ŸŒ Azure Portal participant PIP as ๐ŸŒ Bastion Public IP participant AB as ๐Ÿ›ก๏ธ Azure Bastion participant VM as ๐Ÿ’ป Target VM U->>AP: 1. Login to Azure Portal AP->>U: 2. Portal Interface Loaded U->>AP: 3. Navigate to VM, Click Connect AP->>PIP: 4. Connect to Bastion Public IP PIP->>AB: 5. Forward to Bastion Service AB->>VM: 6. Establish RDP/SSH to Private IP VM->>AB: 7. Connection Established AB->>PIP: 8. Return encrypted tunnel PIP->>AP: 9. Tunnel ready via Public IP AP->>U: 10. Browser-based RDP/SSH Session Note over U,VM: Portal communicates with Bastion via Public IP Note over AB,VM: Bastion to VM uses private network only

Traffic Flow Explanation

This sequence diagram illustrates how traffic flows when establishing a connection through Azure Bastion:

The entire session is encrypted end-to-end, and no public IPs are exposed on the target VMs.

๐ŸŒ Network Security Architecture

graph LR Internet[๐ŸŒ Internet] --> HTTPS[๐Ÿ”’ HTTPS/TLS 1.2+] HTTPS --> Portal[Azure Portal] Portal --> Bastion[Azure Bastion Service] subgraph VNet [Virtual Network 10.0.0.0/16] subgraph BastionSubnet [AzureBastionSubnet 10.0.1.0/26] Bastion NSG1[๐Ÿ›ก๏ธ Bastion NSG] end subgraph VMSubnet [VM Subnet 10.0.2.0/24] VM1[VM-Web-01] VM2[VM-DB-01] NSG2[๐Ÿ›ก๏ธ VM NSG] end end Bastion -.->|RDP 3389/SSH 22| VM1 Bastion -.->|RDP 3389/SSH 22| VM2 style BastionSubnet fill:#e6f3ff,stroke:#0078d4,stroke-width:2px style VMSubnet fill:#f0f8e6,stroke:#28a745,stroke-width:2px style NSG1 fill:#ffd700,stroke:#333,stroke-width:2px style NSG2 fill:#ffd700,stroke:#333,stroke-width:2px

Network Security Explanation

This diagram shows the network security architecture:

๐Ÿ”ง Implementation Command Flow

graph TD Start([๐Ÿš€ Start Implementation]) --> RG[1๏ธโƒฃ Create Resource Group] RG --> VNet[2๏ธโƒฃ Create Virtual Network] VNet --> BSubnet[3๏ธโƒฃ Create AzureBastionSubnet] BSubnet --> VMSubnet[4๏ธโƒฃ Create VM Subnet] VMSubnet --> NSG[5๏ธโƒฃ Create Network Security Groups] NSG --> PIP[6๏ธโƒฃ Create Public IP for Bastion] PIP --> Bastion[7๏ธโƒฃ Create Bastion Host] Bastion --> VM[8๏ธโƒฃ Create Virtual Machines] VM --> Test[9๏ธโƒฃ Test Connectivity] Test --> End([โœ… Implementation Complete]) style Start fill:#28a745,color:white style End fill:#28a745,color:white style RG fill:#0078d4,color:white style VNet fill:#0078d4,color:white style BSubnet fill:#0078d4,color:white style VMSubnet fill:#0078d4,color:white style NSG fill:#ffc107,color:black style PIP fill:#6f42c1,color:white style Bastion fill:#dc3545,color:white style VM fill:#20c997,color:white style Test fill:#fd7e14,color:white

Command Flow Explanation

This diagram shows the logical sequence for implementing Azure Bastion. Each numbered step builds upon the previous one, and the order is critical for successful deployment. The components must be created in this specific sequence due to dependencies between resources.

โš™๏ธ Step-by-Step Implementation

1

Create Resource Group

az group create \
  --name rg-bastion-demo \
  --location eastus

Parameter Explanation:

  • --name: Resource group name (must be unique within subscription)
  • --location: Azure region where resources will be deployed

Purpose: Creates a logical container for all Bastion-related resources. This is the foundation that holds all other components and provides a single management boundary.

Alternative Options:

  • --tags: Add metadata tags for resource organization
  • Common locations: westus2, westeurope, southeastasia
2

Create Virtual Network

az network vnet create \
  --resource-group rg-bastion-demo \
  --name vnet-bastion-demo \
  --address-prefix 10.0.0.0/16 \
  --location eastus

Parameter Explanation:

  • --address-prefix: CIDR block for the entire virtual network (10.0.0.0/16 provides 65,536 IP addresses)
  • --name: Virtual network name
  • --resource-group: References the resource group created in step 1

Purpose: Creates the virtual network foundation that will contain both the Bastion subnet and VM subnets. This establishes the network boundary for secure communication.

Network Planning:

  • /16 network allows for multiple subnets and future expansion
  • Choose non-overlapping address space with on-premises networks
  • Consider Azure reserved addresses (first 4 and last 1 in each subnet)
3

Create AzureBastionSubnet

az network vnet subnet create \
  --resource-group rg-bastion-demo \
  --vnet-name vnet-bastion-demo \
  --name AzureBastionSubnet \
  --address-prefix 10.0.1.0/26

Parameter Explanation:

  • --name: MUST be exactly "AzureBastionSubnet" (case-sensitive, required by Azure)
  • --address-prefix: Must be /26 or larger (minimum 64 IP addresses)
  • --vnet-name: References the virtual network created in step 2

Purpose: Creates the dedicated subnet where Azure Bastion service will be deployed. This subnet is exclusively reserved for Bastion infrastructure.

โš ๏ธ Critical Requirements:
  • Subnet name must be exactly "AzureBastionSubnet"
  • Minimum size is /26 (64 addresses), but /24 recommended for production
  • Cannot host any other resources
  • No user-defined routes (UDR) allowed
4

Create VM Subnet

az network vnet subnet create \
  --resource-group rg-bastion-demo \
  --vnet-name vnet-bastion-demo \
  --name subnet-vms \
  --address-prefix 10.0.2.0/24

Parameter Explanation:

  • --name: Subnet name for virtual machines (can be any valid name)
  • --address-prefix: /24 provides 256 IP addresses (251 usable after Azure reservations)

Purpose: Creates the subnet where target virtual machines will be deployed. VMs in this subnet will be accessible through Bastion without requiring public IP addresses.

Subnet Planning:

  • Size based on expected number of VMs
  • Consider future growth and additional subnets
  • Can have Network Security Groups applied
  • Supports User Defined Routes if needed
5

Create Network Security Group for Bastion

az network nsg create \
  --resource-group rg-bastion-demo \
  --name nsg-bastion \
  --location eastus

Parameter Explanation:

  • --name: Network Security Group name for Bastion subnet

Purpose: Creates firewall rules to control traffic to/from the Bastion subnet. This provides an additional layer of security for the Bastion service.

Configure Bastion NSG Rules

# Allow inbound HTTPS from Internet
az network nsg rule create \
  --resource-group rg-bastion-demo \
  --nsg-name nsg-bastion \
  --name AllowHttpsInbound \
  --protocol Tcp \
  --direction Inbound \
  --priority 1000 \
  --source-address-prefix Internet \
  --source-port-range "*" \
  --destination-address-prefix "*" \
  --destination-port-range 443 \
  --access Allow
# Allow inbound from GatewayManager
az network nsg rule create \
  --resource-group rg-bastion-demo \
  --nsg-name nsg-bastion \
  --name AllowGatewayManagerInbound \
  --protocol Tcp \
  --direction Inbound \
  --priority 1001 \
  --source-address-prefix GatewayManager \
  --source-port-range "*" \
  --destination-address-prefix "*" \
  --destination-port-range 443 \
  --access Allow
# Allow outbound SSH and RDP to VMs
az network nsg rule create \
  --resource-group rg-bastion-demo \
  --nsg-name nsg-bastion \
  --name AllowSshRdpOutbound \
  --protocol "*" \
  --direction Outbound \
  --priority 1000 \
  --source-address-prefix "*" \
  --source-port-range "*" \
  --destination-address-prefix VirtualNetwork \
  --destination-port-ranges 22 3389 \
  --access Allow

NSG Rules Explanation:

  • Rule 1 (Priority 1000): Allows HTTPS traffic from Internet to Bastion (required for user connections)
  • Rule 2 (Priority 1001): Allows Azure management traffic from GatewayManager service tag
  • Rule 3 (Priority 1000 Outbound): Allows Bastion to connect to VMs via SSH (22) and RDP (3389)

Service Tags Used:

  • Internet: Represents all public Internet addresses
  • GatewayManager: Azure service tag for gateway management traffic
  • VirtualNetwork: Represents all addresses in the virtual network
6

Create Public IP for Bastion

az network public-ip create \
  --resource-group rg-bastion-demo \
  --name pip-bastion \
  --sku Standard \
  --allocation-method Static \
  --location eastus

Parameter Explanation:

  • --sku Standard: Required for Bastion (Basic SKU not supported)
  • --allocation-method Static: Ensures IP address doesn't change
  • --name: Public IP resource name

Purpose: Creates the public IP address that Azure Bastion will use to receive inbound connections from the Internet. This is the only public IP required in the entire solution.

โš ๏ธ Requirements:
  • Must be Standard SKU (Basic not supported)
  • Must be Static allocation
  • Must be in same region as Bastion

Additional Options:

  • --zone {1,2,3}: Specify availability zone for zone-redundant deployment
  • --dns-name-label: Create DNS name like mybastion.eastus.cloudapp.azure.com
7

Create Azure Bastion Host

az network bastion create \
  --resource-group rg-bastion-demo \
  --name bastion-demo \
  --public-ip-address pip-bastion \
  --vnet-name vnet-bastion-demo \
  --location eastus \
  --sku Standard

Parameter Explanation:

  • --public-ip-address: References the public IP created in step 6
  • --vnet-name: Virtual network containing AzureBastionSubnet
  • --sku Standard: Bastion SKU (Basic or Standard)

Purpose: Deploys the actual Azure Bastion service into the AzureBastionSubnet. This process takes 10-15 minutes to complete as Azure provisions the managed infrastructure.

SKU Comparison:

  • Basic SKU: Up to 25 concurrent sessions, browser-based access only
  • Standard SKU: Up to 50 concurrent sessions, supports native client access, file transfer, IP-based connections
โš ๏ธ Deployment Notes:
  • Deployment takes 10-15 minutes
  • Automatically finds AzureBastionSubnet in specified VNet
  • Creates managed network interface in the subnet
8

Create Test Virtual Machine

az vm create \
  --resource-group rg-bastion-demo \
  --name vm-web-01 \
  --image Ubuntu2204 \
  --subnet subnet-vms \
  --vnet-name vnet-bastion-demo \
  --admin-username azureuser \
  --authentication-type ssh \
  --generate-ssh-keys \
  --public-ip-address "" \
  --size Standard_B2s

Parameter Explanation:

  • --image Ubuntu2204: VM image (Ubuntu 22.04 LTS)
  • --subnet: VM subnet created in step 4
  • --public-ip-address "": Explicitly prevents public IP creation
  • --generate-ssh-keys: Creates SSH keys for authentication
  • --size Standard_B2s: VM size (2 vCPUs, 4 GB RAM)

Purpose: Creates a virtual machine without a public IP address to test Bastion connectivity. This VM can only be accessed through Azure Bastion.

Security Benefits:

  • No public IP = no direct Internet exposure
  • No SSH/RDP ports exposed to Internet
  • Access only through Bastion's encrypted tunnel
  • Centralized access logging and monitoring

Alternative: Create Windows VM

az vm create \
  --resource-group rg-bastion-demo \
  --name vm-win-01 \
  --image Win2022Datacenter \
  --subnet subnet-vms \
  --vnet-name vnet-bastion-demo \
  --admin-username azureuser \
  --admin-password 'ComplexPassword123!' \
  --public-ip-address "" \
  --size Standard_B2s

Windows VM Notes:

  • Uses password authentication instead of SSH keys
  • Password must meet complexity requirements
  • Accessible via RDP through Bastion

๐Ÿ” Advanced Configuration Options

Enable Native Client Support (Standard SKU)

az network bastion update \
  --resource-group rg-bastion-demo \
  --name bastion-demo \
  --enable-native-client true

Native Client Benefits:

Usage Example:

az network bastion ssh --name bastion-demo --resource-group rg-bastion-demo --target-resource-id /subscriptions/.../vm-web-01 --auth-type ssh-key --username azureuser

Configure Scale Units (Premium SKU)

az network bastion update \
  --resource-group rg-bastion-demo \
  --name bastion-demo \
  --scale-units 10

Scale Units Explanation:

๐Ÿงช Testing Connectivity

graph LR Start([๐Ÿ” Start Testing]) --> Portal[Open Azure Portal] Portal --> VM[Navigate to VM] VM --> Connect[Click Connect] Connect --> Bastion[Select Bastion] Bastion --> Auth[Enter Credentials] Auth --> Session[๐ŸŽ‰ Connected!] style Start fill:#28a745,color:white style Session fill:#28a745,color:white style Portal fill:#0078d4,color:white style VM fill:#0078d4,color:white style Connect fill:#ffc107,color:black style Bastion fill:#dc3545,color:white style Auth fill:#6f42c1,color:white

Testing Steps:

  1. Portal Access: Log into Azure Portal with appropriate permissions
  2. VM Navigation: Find your target virtual machine
  3. Connection Method: Click "Connect" and select "Bastion"
  4. Authentication: Enter VM credentials (username/password or SSH key)
  5. Session Start: Browser-based terminal or RDP session opens

๐Ÿ“Š Verification Commands

Verify Bastion Deployment

az network bastion show \
  --resource-group rg-bastion-demo \
  --name bastion-demo \
  --output table

Check Subnet Configuration

az network vnet subnet show \
  --resource-group rg-bastion-demo \
  --vnet-name vnet-bastion-demo \
  --name AzureBastionSubnet \
  --output table

Verify VM Network Configuration

az vm show \
  --resource-group rg-bastion-demo \
  --name vm-web-01 \
  --show-details \
  --query '{Name:name, PrivateIp:privateIps, PublicIp:publicIps, PowerState:powerState}' \
  --output table

Expected Results:

๐Ÿ›ก๏ธ Security Best Practices

๐Ÿ” Security Recommendations

๐Ÿ’ฐ Cost Optimization

Pricing Considerations:

Cost Savings:

๐Ÿšจ Troubleshooting Common Issues

Common Problems & Solutions:

๐Ÿ“š Additional Resources

๐ŸŽฏ Summary

Azure Bastion provides a secure, managed solution for VM connectivity without exposing public IP addresses. The implementation requires careful attention to subnet naming, sizing, and network security group configuration. Once deployed, it offers a streamlined way to access VMs through the Azure Portal with enterprise-grade security.