The goal
You need a Linux VM for a quick test. By the end of this post you'll have one running, you'll be able to SSH to it, port 22 will be open only to your own IP address and you'll know how to delete it all.
You need the Azure CLI and permission to create resources. If you haven't used the CLI yet, start with Azure CLI first steps.
Step 1: pick a subscription and a resource group
A resource group is a folder for related resources. Deleting the group deletes everything in it, which makes clean-up simple.
az login
az account show --query "{name:name, id:id}" -o table
az group create --name rg-vm-lab --location centralindia
Check the subscription name before going further. Creating a test VM in a production subscription is an easy mistake.
Step 2: check that the size is available
Not every size is offered in every region:
az vm list-skus --location centralindia --size Standard_B2s \
--resource-type virtualMachines --all \
--query "[].{name:name, restrictions:restrictions[0].reasonCode}" -o table
If restrictions shows NotAvailableForSubscription, try another size or region. The same applies if the create command later fails with SkuNotAvailable.
Step 3: create the VM
az vm create \
--resource-group rg-vm-lab \
--name vm-lab-01 \
--image Ubuntu2404 \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
This one command also creates a virtual network, a subnet, a network security group (NSG), a public IP, a network interface and an OS disk.
--generate-ssh-keys uses your existing key at ~/.ssh/id_rsa.pub, or creates one if you don't have one. Back up the private key if you intend to keep this VM.
If Ubuntu2404 isn't recognized by your CLI version, list the aliases it knows:
az vm image list --output table
Step 4: connect
IP=$(az vm show -d -g rg-vm-lab -n vm-lab-01 --query publicIps -o tsv)
echo "$IP"
ssh azureuser@"$IP"
Once you're in, run a quick check:
hostname
df -h /
free -h
Step 5: limit SSH to your IP
Depending on your CLI version and options, the default NSG rule may allow SSH from anywhere. Look at it:
az network nsg list -g rg-vm-lab --query "[].name" -o tsv
az network nsg rule list -g rg-vm-lab --nsg-name vm-lab-01NSG \
--query "[].{name:name, port:destinationPortRange, source:sourceAddressPrefix, access:access}" -o table
The usual NSG name is the VM name followed by NSG, but use whatever the first command shows. The rule is usually called default-allow-ssh. Restrict it to your public IP:
MYIP=$(curl -s https://ifconfig.me)
az network nsg rule update -g rg-vm-lab --nsg-name vm-lab-01NSG \
--name default-allow-ssh \
--source-address-prefixes "$MYIP/32"
Warning
Leaving port 22 open to the internet invites constant login attempts within minutes. Keep it limited, and for anything long-lived use Azure Bastion or a VPN instead of a public IP.
Step 6: stop paying when you're not using it
# Stops the VM but you still pay for compute
az vm stop -g rg-vm-lab -n vm-lab-01
# Releases the compute, so compute charges stop
az vm deallocate -g rg-vm-lab -n vm-lab-01
# Start it again
az vm start -g rg-vm-lab -n vm-lab-01
Disks and the public IP still cost money while the VM is deallocated. See stop vs deallocate for the details. A nightly schedule also helps:
az vm auto-shutdown -g rg-vm-lab -n vm-lab-01 --time 1830
The time is in UTC.
Common errors
| Error or symptom | Likely cause | Fix |
|---|---|---|
SkuNotAvailable | Size isn't offered in this region or zone | Pick another size or region |
QuotaExceeded | vCPU limit reached | Use a smaller size or request more quota |
AuthorizationFailed | You lack rights on the resource group | Ask for Contributor on the group |
Permission denied (publickey) | Wrong user or wrong key | Use azureuser, and ssh -i with the right key |
| SSH times out | Your IP changed, or the NSG blocks you | Update the NSG rule with your current IP |
Connection refused | VM is still booting, or sshd isn't running | Wait a minute, then check boot diagnostics |
For a deeper walk-through of connection problems, read VM unreachable over RDP or SSH.
Step 7: delete everything
See what's in the group first:
az resource list -g rg-vm-lab --query "[].{name:name, type:type}" -o table
Then delete it:
az group delete --name rg-vm-lab --yes --no-wait
Caution
az group deleteremoves every resource in the group, and there's no undo for most of them. Read the list above first, and make sure the group holds only your lab resources.
Prevent it next time
- Put each experiment in its own resource group, with a tag that names the owner.
- Set auto-shutdown on every test VM.
- Add a budget alert so a forgotten VM doesn't go unnoticed.
- When you build something real, follow the standalone production VM guide instead of these defaults.