Creating VMs¶
Create new Azure VMs with azlin's new command - optimized for development workflows with automatic configuration and cloud-init provisioning.
Quick Start¶
# Create a VM with sensible defaults (128GB RAM)
azlin new
# Create with custom name
azlin new --name my-dev-vm
# Create and clone a repository
azlin new --repo https://github.com/yourusername/yourproject
Overview¶
The azlin new command provisions Azure VMs with:
- Pre-installed development tools (Docker, Python, Node.js, Git, etc.)
- Automatic SSH key management via Azure Key Vault
- Optional NFS storage mounting for shared home directories
- Flexible sizing from 8GB to 256GB RAM
- Template support for repeatable configurations
- Bastion integration for secure private networking
Command Reference¶
Essential Options¶
| Option | Description | Default |
|---|---|---|
--name TEXT | Custom VM name | Auto-generated (azlin-vm-xxxxx) |
--size [s\|m\|l\|xl] | Size tier: s(8GB), m(64GB), l(128GB), xl(256GB) | l (128GB) |
--vm-size TEXT | Exact Azure VM size (overrides --size) | Based on size tier |
--region TEXT | Azure region | From config or eastus |
--resource-group TEXT | Azure resource group | From config |
--repo TEXT | GitHub repository URL to clone | None |
Advanced Options¶
| Option | Description | Default |
|---|---|---|
--pool INTEGER | Number of VMs to create in parallel | 1 |
--no-auto-connect | Skip automatic SSH connection after provision | Enabled |
--template TEXT | Template name for VM configuration | None |
--nfs-storage TEXT | NFS storage account to mount as home | None |
--no-nfs | Skip NFS storage mounting | NFS enabled if configured |
--no-bastion | Always create public IP (skip bastion) | Bastion auto-detected |
--bastion-name TEXT | Explicit bastion host name | Auto-detected |
-y, --yes | Accept all defaults (non-interactive) | Interactive |
Size Tiers Explained¶
azlin provides four convenience size tiers that map to optimal Azure VM SKUs:
| Tier | RAM | vCPUs | Azure VM Size | Use Case |
|---|---|---|---|---|
| s (small) | 8GB | 2 | Standard_D2s_v3 | Lightweight dev, testing |
| m (medium) | 64GB | 16 | Standard_E16s_v5 | Standard development |
| l (large) | 128GB | 32 | Standard_E32s_v5 | Default - ML, large projects |
| xl (extra-large) | 256GB | 64 | Standard_E64s_v5 | Training, heavy workloads |
Custom Sizes
Use --vm-size with any Azure VM SKU for exact control:
Common Usage Patterns¶
Basic VM Creation¶
# Default VM (128GB RAM, auto-name, auto-connect)
azlin new
# Small VM for testing (8GB RAM)
azlin new --size s --name test-vm
# Medium VM with custom name (64GB RAM)
azlin new --size m --name dev-environment
What happens:
- Generates unique VM name (if not provided)
- Creates or retrieves SSH keys from Azure Key Vault
- Provisions VM with cloud-init configuration
- Installs development tools (Docker, Python, uv, Git, etc.)
- Auto-connects via SSH (unless
--no-auto-connect)
Development with Repository¶
# Clone repository during provisioning
azlin new --repo https://github.com/youruser/yourproject
# Large VM for ML project
azlin new --size xl --name ml-training \
--repo https://github.com/yourteam/ml-pipeline
What happens:
- Provisions VM as normal
- Clones repository to
/home/azureuser/yourproject - Connects you directly to the VM
- Repository ready to use immediately
Team Environments with NFS¶
# Create VM with shared home directory
azlin new --nfs-storage myteam-shared --name worker-1
# Multiple workers sharing same home directory
azlin new --nfs-storage myteam-shared --name worker-2
azlin new --nfs-storage myteam-shared --name worker-3
What happens:
- Mounts existing NFS storage account as
/home/azureuser - All files, configs, and code shared across VMs
- Perfect for distributed workloads or team collaboration
NFS Storage Must Exist
Create NFS storage first with azlin storage create myteam-shared
Parallel VM Provisioning¶
# Create 5 identical VMs simultaneously
azlin new --pool 5 --size l --name batch-job
# Creates: batch-job-1, batch-job-2, batch-job-3, batch-job-4, batch-job-5
What happens:
- Provisions all VMs in parallel (much faster)
- Each gets unique name with numeric suffix
- All VMs ready simultaneously
- No automatic connection (use
azlin listto see them)
Template-Based Provisioning¶
# Create VM from saved template
azlin new --template dev-vm
# Template overrides defaults for size, region, tools, etc.
What happens:
- Loads configuration from template
- Applies template defaults (size, region, software, etc.)
- Any explicit flags override template settings
See: Templates Guide for template creation
Private VMs with Bastion¶
# Auto-detect bastion (default behavior)
azlin new --name private-vm
# Explicitly specify bastion
azlin new --name private-vm --bastion-name my-bastion
# Force public IP (skip bastion)
azlin new --name public-vm --no-bastion
What happens:
- If bastion detected: Creates private VM (no public IP)
- If no bastion: Creates VM with public IP
- Connection automatically routed through bastion when present
See: Azure Bastion Guide
Non-Interactive (CI/CD)¶
# Accept all defaults without prompts
azlin new --yes --name ci-runner --size m
# Provision and run command without interaction
azlin new --yes --size xl -- python train.py --epochs 100
What happens:
- No interactive prompts
- Uses defaults for all unspecified options
- Perfect for automation and scripts
Advanced Examples¶
GPU-Enabled VM¶
Multi-Region Deployment¶
# Deploy to specific regions
azlin new --region eastus --name east-vm
azlin new --region westus --name west-vm
azlin new --region northeurope --name eu-vm
Execute Command Post-Provisioning¶
# Run command after VM is ready (use -- separator)
azlin new --size xl --repo https://github.com/user/ml-project -- \
python train.py --config production.yaml
# Install additional software
azlin new --size m -- \
"sudo apt-get update && sudo apt-get install -y postgresql-client"
Provisioning Time¶
Typical provisioning times:
- VM Creation: 3-5 minutes
- Cloud-init (software): 5-10 minutes
- Total: ~10-15 minutes for fully configured VM
Watch Progress
Cloud-init logs available via: azlin logs <vm-name>
What Gets Installed¶
Every azlin VM comes with:
Development Tools: - Python 3.13 (with uv package manager) - Docker & Docker Compose - Node.js & npm - Git & GitHub CLI (gh) - tmux, vim, htop
Cloud Tools: - Azure CLI (authenticated) - kubectl (Kubernetes) - Terraform
System Configuration: - Docker added to user's group (no sudo needed) - SSH keys stored in Key Vault - Automatic security updates enabled
Troubleshooting¶
VM Provisioning Fails¶
# Check Azure quota
azlin quota
# View detailed error logs
azlin logs <vm-name>
# Try different region
azlin new --region westus
Can't Connect After Creation¶
# Check VM status
azlin status --vm <vm-name>
# Verify SSH keys
az keyvault secret list --vault-name <vault-name>
# Manual connection
azlin connect <vm-name>
Cloud-init Incomplete¶
# SSH to VM and check cloud-init status
azlin connect <vm-name> -- cloud-init status
# View cloud-init logs
azlin logs <vm-name>
Out of Quota¶
# Check current quota
azlin quota
# Request quota increase via Azure Portal
# Or try different region/size
azlin new --region westus --size m
See: Quota Management
Related Commands¶
azlin list- View all VMsazlin connect- SSH to VMazlin status- Check VM statusazlin clone- Clone existing VMazlin storage mount- Attach shared storage
Source Code¶
Last updated: 2025-11-24