Uploading files to Azure VMs using Azure Bastion

Hello there!

Recently, I was working on an Azure project and one of my tasks involved a step where I had to upload some files to a Linux virtual machine. However, the environment was locked down and I did not have direct SSH access to the VM. The only option for remote access was this cool service called “Azure Bastion”. You probably already know what it does but in case you don’t, you can read more about this fully managed RDP/SSH solution.

So, during my research what would be the quickest approach to perform this upload, I first thought that I could upload the file to a remote cloud storage e.g. OneDrive or even an Azure Storage Account. But, I didn’t want to involve more services and at some point this post flashed into my mind which says that Azure Bastion supports file uploads with its “Native Client Support” feature.

I though “Great, I already use Bastion!” What about the prerequisites? Easy stuff:

  • Azure CLI >= 2.32
  • The VM resource ID

Keep reading to find out how you can try this by yourself.

What you will need is of course a Bastion, a Linux VM and some Virtual Networks. If you have none of these, go to Azure Quickstart Templates and deploy this template by clicking on “Deploy to Azure”. Sign in to your Azure Subscription and fill in the template parameters. You will need to define at least the Resource Group along with a username and a password for your VM. Once completed, you should have a Resource Group with the following resources:

  • A hub vnet
  • A spoke vnet
  • A bastion host on the Basic tier (you will later need to upgrade to Standard)
  • A public IP address
  • A Linux VM with its disk and network interface

For the file upload feature to work, your Bastion host must be on the Standard tier and the “Native Client Support” option must be enabled. To do this on the Azure Portal, navigate to your Bastion host resource and under “Settings” select the “Configuration” option. In this page, ensure that the “Standard” tier is selected and the “Native Client Support” box is checked.

Click “Apply” to deploy any changes that you made.

Open a Terminal window and run the following commands replacing <subscription id> by the ID of the subscription that contains the Bastion host (not the VM):

az login
az account set -s <subscription id>

Run the following command to create a tunnel between your PC and the VM over the Bastion host, providing the right parameter values for your environment:

az network bastion tunnel --name <bastion name> --resource-group <resource group name> --target-resource-id <VM resourceId> --resource-port <target VM port> --port <local machine port>
  • bastion name: the name of your Bastion host
  • resource Group name: the name of the resource group that contains your Bastion host
  • VM resourceId: you can find it in the properties section of your VM in the Azure Portal
  • Target VM port: it is the port where SSH runs on the targer VM, typically 22.
  • Local machine port: choose a non-reserved TCP port on your PC. You will use it later for the file transfer.

Tip: In case you receive a message that the bastion host was not found, make sure that you are targeting the right Azure Subscription in your Azure CLI session. More specifically, if you are on an environment that uses Azure Landing Zones, most probably your bastion host is deployed in the “Connectivity” subscription but your VM is on an Application Landing Zone. Furthermore, to use the Bastion host, you need to have the “Reader” role on the Bastion host as well as the Virtual Network where it lives.

Once the tunnel is successfully created you will see the message below:

Opening tunnel on port: 59999
Tunnel is ready, connect on port 59999
Ctrl + C to close

Now you can perform the file upload using your favourite SFTP/SCP client. I use WinSCP. To connect to your VM use the following host details:

Host: localhost
Port: The local machine port that you provided earlier in the ‘az network bastion tunnel’ command
Username: The VM username
Password: The VM password

All set! Now you are ready to perform the file upload: