You will deploy an Azure VM into your VNet, bootstrap it with cloud-init, and access it via key-based SSH only. By the end you will have a secured, reproducible cloud server configured at first boot.

Learning Objectives

  • Deploy a VM with SSH-key authentication.
  • Bootstrap packages and config with cloud-init.
  • Restrict inbound access to your IP only.
  • Time: ~2 hours · Difficulty: Intermediate · Prereqs: a VNet and the Azure CLI.

Architecture Overview

Environment Setup

You will need: a VNet/subnet (from the VNet lab), the Azure CLI, and an SSH keypair.

Before you begin: note your public IP to scope SSH access.

Step-by-Step Execution

01
Write a cloud-init file
# cloud-init.yaml
#cloud-config
package_update: true
packages: [nginx]
runcmd:
  - systemctl enable --now nginx
02
Deploy the VM with key auth and cloud-init
az vm create -n web01 --image Ubuntu2204 --vnet-name vnet-a --subnet web --admin-username taki --ssh-key-values ~/.ssh/id_ed25519.pub --custom-data cloud-init.yaml
03
Restrict SSH to your IP
$ az vm open-port -n web01 --port 22 --priority 100 && az network nsg rule update -g tyf-rg --nsg-name web01NSG -n open-port-22 --source-address-prefixes 203.0.113.10/32
"sourceAddressPrefix": "203.0.113.10/32"

Progress So Far

Testing & Validation

ssh taki@$(az vm show -d -n web01 --query publicIps -o tsv) 'systemctl is-active nginx'

You should connect with your key (no password) and see active, proving cloud-init bootstrapped the server.

Troubleshooting
  • cloud-init did not run: check /var/log/cloud-init-output.log on the VM.
  • SSH times out: confirm the NSG allows port 22 from your current IP.
  • Password prompt: deploy with --ssh-key-values, not --admin-password.

Extension Ideas

Key Results

  • Deployed a cloud VM bootstrapped automatically at first boot.
  • Enforced key-only SSH with no password authentication.
  • Restricted inbound SSH to a single source IP.
  • Verified the service end to end over SSH.