Hey everyone! If you’re like me, you’ve probably faced this challenge: all your important development resources—App Services, databases, internal tools—are tucked away safely inside a private Azure network. That’s great for security, but it can be a real headache when you just want to connect from your local machine and get some work done.
This guide is my personal playbook for setting this up. We’ll create a secure tunnel to a “jump host” (just a simple Linux VM) and then use it as a gateway to securely access anything in our private network—all from the comfort of VS Code and your favorite local tools.
What You’ll Need
Before we dive in, let’s get our tools ready. Make sure you have these installed on your Windows machine:
- Windows Subsystem for Linux (WSL2)
- Visual Studio Code
- VS Code Remote - SSH Extension
- Azure CLI
A quick but important note on the Azure side: your Azure Bastion host must be on the Standard SKU. The basic one won’t work here because we need the native client connection feature.
Step 1: The “Magic Tunnel” Script
The heart of this entire setup is a command: az network bastion tunnel. It uses the Azure CLI to create a secure, encrypted tunnel from your local machine, through Bastion, to your jump host.
To make our lives easier, let’s wrap this in a simple script. I run this from my WSL2 terminal every morning.
Save this as connect-bastion.sh in your WSL2 environment:
#!/bin/bash
# A friendly script to connect to our Azure jump host via Bastion.
# --- Easy Configuration ---
# Just fill in your details here!
BASTION_NAME="your-bastion-host-name"
BASTION_RG="your-bastion-resource-group"
TARGET_VM_ID="/subscriptions/your-subscription-id/resourceGroups/your-vm-resource-group/providers/Microsoft.Compute/virtualMachines/your-jump-host-vm"
# This is the local port we'll use to SSH into the jump host.
# You can change it if 2222 is already in use on your machine.
LOCAL_SSH_PORT="2222"
REMOTE_SSH_PORT="22" # This is almost always 22 for the VM's SSH port.
# --- The Magic ---
echo "Let's get you logged into Azure..."
az login
echo "Starting the Bastion tunnel to your jump host..."
# This command runs in the background (&) so you can keep using your terminal.
az network bastion tunnel \
--name "$BASTION_NAME" \
--resource-group "$BASTION_RG" \
--target-resource-id "$TARGET_VM_ID" \
--resource-port "$REMOTE_SSH_PORT" \
--port "$LOCAL_SSH_PORT" &
TUNNEL_PID=$!
echo "Success! Tunnel is running in the background (PID: $TUNNEL_PID)."
echo "You can now connect to your jump host in VS Code."
echo "Press Ctrl+C to close this tunnel when you're done."
# This 'wait' command keeps the script alive until you manually stop it.
wait $TUNNEL_PID
How to use it:
- Open your WSL2 terminal.
- Make the script executable:
chmod +x connect-bastion.sh. - Run it:
./connect-bastion.sh.
The script will open a browser for you to log into Azure. Once you do, it will establish the tunnel and stay running. Just minimize this terminal window and let it do its thing.
Step 2: Connecting VS Code to the Jump Host
Now for the fun part. Let’s get VS Code connected to our jump host through the tunnel we just opened.
-
Open your SSH Config File: In VS Code, press
Ctrl+Shift+Pto open the command palette and typeRemote-SSH: Open Configuration File.... Select the main config file (e.g.,C:\Users\YourUser\.ssh\config). -
Add Your Jump Host: Add a new entry like this. This tells VS Code how to find and authenticate with our jump host.
# JUMP HOST - VIA AZURE BASTION
Host my-azure-jump-host
HostName 127.0.0.1
User your_vm_username
Port 2222
IdentityFile ~/.ssh/your_private_key_for_the_vm
- Host: A nickname for the connection. Call it whatever you want!
- HostName:
127.0.0.1because we’re connecting to the local end of our Bastion tunnel. - User: The username you use to log into the Linux VM.
- Port: The
LOCAL_SSH_PORTyou defined in the script (2222). - IdentityFile: The path to the SSH private key that can access your jump host. I keep mine in WSL, so the path might look like
\\wsl$\Ubuntu\home\myuser\.ssh\id_rsa.
- Connect! Go to the “Remote Explorer” tab in VS Code. You should see “my-azure-jump-host” in the list. Click the little “Connect to Host” icon next to it.
A new VS Code window will open, but this one is running entirely on your jump host. You can use the terminal, edit files, and run commands as if you were logged directly into the VM.
Step 3: The Real Magic - Accessing Services with Port Forwarding
Okay, so we’re inside the jump host. But what if you want to use a tool on your local Windows machine—like your browser or a database GUI—to access a service that only the jump host can see?
This is where SSH local port forwarding comes in. It lets us forward a port on our local machine through the SSH connection to any destination the jump host can reach.
Let’s say you have a private App Service with a web portal at my-private-app.azurewebsites.net. You can’t reach it from your browser, but the jump host can. We can tell VS Code to automatically forward a local port (like 8080) to that address.
Go back to your SSH config file (~/.ssh/config) and add the LocalForward directive to your host entry:
# JUMP HOST - VIA AZURE BASTION
Host my-azure-jump-host
HostName 127.0.0.1
User your_vm_username
Port 2222
IdentityFile ~/.ssh/your_private_key_for_the_vm
# --- PORT FORWARDING MAGIC ---
# Forward my local port 8080 to the private app service's web port (443)
LocalForward 8080 my-private-app.azurewebsites.net:443
# Forward my local port 1433 to a private SQL Server
LocalForward 1433 my-private-sql-server.database.windows.net:1433
Now, simply reconnect to your host in VS Code. The forwarding happens automatically!
Your new workflow:
- Run
./connect-bastion.shin your WSL terminal. - Connect to
my-azure-jump-hostin VS Code. - Open your local Windows browser and go to
https://localhost:8080. You will now see your private App Service! - Open your local SQL Server Management Studio and connect to
localhost, 1433. You will now be connected to your private SQL database!
You can add as many LocalForward lines as you need. It’s an incredibly powerful way to bring all of Azure’s private resources right to your local machine, securely.
I hope this helps you streamline your Azure development workflow as much as it has for me. Happy coding!