Microsoft Azure — Virtual Machines
Azure VMs, VM sizes, availability sets, availability zones, disks, and provisioning..
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
- ✓Azure subscription with Contributor access, Azure CLI 2.50+ installed, PowerShell 7+ with Az module 10.0+, basic knowledge of VNet/subnet concepts, familiarity with JSON/YAML, and a GitHub account for IaC version control.
Virtual Machines is like having a specialized tool that handles virtual machines in the Microsoft cloud — you manage the configuration, Azure handles the infrastructure.
Azure is Microsoft's cloud computing platform offering over 200 services. This article covers virtual machines with production-ready configurations, best practices, and hands-on examples.
Azure VMs: The Foundation of IaaS
Azure Virtual Machines are the bread and butter of Infrastructure as a Service (IaaS) on Microsoft's cloud. They give you full control over the operating system, installed software, and networking. Unlike PaaS services, VMs require you to manage patching, scaling, and high availability yourself. This is both a blessing and a curse: you get flexibility, but you also inherit operational overhead. In production, the most common mistake is treating VMs like on-premises servers—spinning them up, installing everything manually, and hoping they never fail. That approach leads to configuration drift, security gaps, and painful recovery. Instead, treat VMs as cattle, not pets. Use infrastructure as code (IaC) to define every aspect: size, disk, network, and extensions. Start with a clear naming convention and tagging strategy. For example, use env:prod, app:payment, role:web to filter and manage resources at scale. Without tags, you'll drown in a sea of unnamed VMs.
Choosing the Right VM Size and Series
Azure offers dozens of VM series: general-purpose (D-series), compute-optimized (F-series), memory-optimized (E-series), and more. Picking the wrong size leads to either overspending or performance bottlenecks. For production, never use the B-series burstable VMs for steady-state workloads—they rely on CPU credits and will throttle under sustained load. Instead, start with D-series for most web apps and APIs. Use E-series for in-memory caches or databases. For GPU workloads, NC or ND series. Always benchmark with your actual workload. A common trap is choosing a VM with too little memory, causing the OS to swap and kill performance. Use Azure Monitor to track memory pressure. Also consider the new generation: Dv5 and Ev5 offer better price-performance than older Dv3. For disk, always use Premium SSD for OS disks in production—Standard HDD is only for dev/test. For data disks, consider Ultra Disk for high IOPS workloads like databases.
Networking: VNet, Subnets, and NSGs Done Right
Every Azure VM lives inside a Virtual Network (VNet). You must plan your IP address space carefully—don't use /16 for everything. Use /24 subnets per tier: web, app, data. Network Security Groups (NSGs) are your first line of defense. Default-deny inbound, allow only necessary ports. For production, never open SSH (22) or RDP (3389) to the internet. Use Azure Bastion or a jumpbox. Also, enable NSG flow logs to detect anomalies. Another common mistake: placing all VMs in the same subnet. If one VM is compromised, lateral movement is trivial. Use Application Security Groups (ASGs) to group VMs by role and define NSG rules based on ASGs, not IPs. This decouples security from IP addresses. For high availability, deploy VMs in an Availability Set or Availability Zone. Availability Sets protect against rack failures; Zones protect against datacenter failures. For critical workloads, use Zones.
Storage: Managed Disks, Caching, and Backup
Azure Managed Disks are the default and should always be used over unmanaged disks (storage accounts). They offer better reliability, availability, and integration with availability sets. For OS disks, Premium SSD is the minimum for production. For data disks, choose based on IOPS needs: Standard SSD for general purpose, Premium SSD for high performance, Ultra Disk for extreme latency-sensitive workloads. Disk caching can significantly improve read performance: set OS disk caching to ReadWrite, data disks to ReadOnly for read-heavy workloads. But be careful—write-heavy databases should disable caching on data disks to avoid data corruption. Always enable Azure Backup for VMs. It provides application-consistent backups for Windows and file-consistent for Linux. Set a retention policy that meets your RPO/RTO. For critical data, also use Azure Site Recovery for cross-region replication. A common mistake is forgetting to back up data disks attached to a VM—backup only covers the VM by default, but you can include data disks.
High Availability: Availability Sets vs Zones
For production, you need redundancy. Azure offers two options: Availability Sets and Availability Zones. Availability Sets distribute VMs across up to 3 fault domains (racks) and update domains (maintenance windows). They protect against hardware failures and planned maintenance within a datacenter. Availability Zones place VMs in physically separate datacenters within a region, protecting against entire datacenter failures. For most production workloads, use Availability Zones—they offer higher SLA (99.99% vs 99.95% for multi-VM in set). However, Zones incur inter-zone network latency (typically <2ms). For stateful applications like databases, you need to handle data replication yourself (e.g., SQL Always On, MongoDB replica sets). A common mistake is deploying VMs in the same zone thinking they're in different zones—always check the zone property. Also, load balancers must be zone-redundant or zone-specific. Use Azure Standard Load Balancer with zone-redundant frontend.
Scaling: Scale Sets and Autoscale
For stateless workloads, use Virtual Machine Scale Sets (VMSS) with autoscale. VMSS allows you to manage a group of identical VMs that can scale in/out based on metrics like CPU, memory, or custom metrics. Always use a custom image or VMSS with the latest OS image to ensure consistency. For production, configure a minimum instance count (e.g., 2) and maximum (e.g., 10). Set scale-out rules to be aggressive (e.g., CPU > 75% for 5 minutes) and scale-in rules to be conservative (e.g., CPU < 30% for 15 minutes) to avoid thrashing. Use Azure Monitor autoscale with multiple profiles for different times of day. A common mistake is not setting a scale-in policy—by default, the newest VM is removed, which may cause connection draining issues. Use the 'NewestVM' or 'OldestVM' policy based on your needs. Also, integrate with Azure Load Balancer health probes to ensure only healthy instances receive traffic.
Configuration Management with Extensions and Desired State
After provisioning a VM, you need to configure it—install software, apply settings, join domains. Azure VM Extensions automate this. Common extensions: Custom Script Extension (run scripts), DSC (Desired State Configuration), Chef, Puppet. For production, use Custom Script Extension to bootstrap configuration, but avoid embedding secrets in scripts. Instead, use Azure Key Vault to pull secrets at runtime. For Windows, DSC is powerful for ensuring consistent state. For Linux, use cloud-init for initial setup and then configuration management tools like Ansible or Chef. A common mistake is relying on manual SSH/RDP to configure VMs—this is error-prone and not repeatable. Always use extensions or configuration management tools. Also, extensions run as part of VM provisioning; if they fail, the VM may be in an inconsistent state. Monitor extension status and set up alerts. For scale sets, use the extensions profile to apply to all instances.
Monitoring and Diagnostics: Azure Monitor and Log Analytics
You can't manage what you don't measure. Enable Azure Monitor for every VM. At minimum, collect metrics like CPU, memory, disk IOPS, and network. Use Azure Monitor alerts to notify on high CPU, disk space, or VM unavailability. For deeper analysis, install the Log Analytics agent (or Azure Monitor agent) to collect logs and performance counters. Create a Log Analytics workspace and configure data sources. For production, set up alerts for common failure modes: disk space < 10%, memory > 90%, CPU > 80% for extended periods. Also enable boot diagnostics to capture serial console output—invaluable for troubleshooting boot failures. A common mistake is not setting up alerts for VM heartbeat—if a VM stops responding, you want to know immediately. Use VM Insights (previously Service Map) to visualize dependencies between VMs and processes. This helps during incident response.
Security: Identity, Encryption, and Updates
Security for Azure VMs starts with identity. Use managed identities for Azure resources instead of storing credentials in VMs. This allows VMs to authenticate to Azure services without secrets. For OS-level access, use Azure AD authentication for Windows VMs (SSH key for Linux). Enable Azure Disk Encryption (ADE) for OS and data disks using Azure Key Vault. ADE uses BitLocker for Windows and DM-Crypt for Linux. For production, encrypt all disks. Also, enable just-in-time (JIT) VM access from Microsoft Defender for Cloud to reduce exposure of management ports. For patching, use Azure Update Management to schedule updates and get compliance reports. A common mistake is not applying security updates promptly—use automatic VM guest patching for Windows (available in preview) or schedule maintenance windows. Also, restrict network traffic with NSGs and use Azure Firewall for egress filtering. Finally, enable Azure Defender for Servers for threat detection.
Cost Management and Right-Sizing
Azure VMs can be expensive if not managed. Start with right-sizing: use Azure Advisor recommendations to identify underutilized VMs (CPU < 5% and memory < 20% for 7 days). Downsize or shut them down during off-hours. Use Azure Cost Management + Billing to set budgets and alerts. For production VMs that run 24/7, buy Reserved Instances or use Azure Savings Plan for compute. For dev/test, use Azure Dev/Test pricing or spot VMs (if interruptible). Another cost-saving technique: use Azure Hybrid Benefit if you have Windows Server or SQL Server licenses with Software Assurance. Also, consider using Azure Dedicated Hosts only if you need physical isolation—they're expensive. A common mistake is leaving VMs running when not needed. Use auto-shutdown for dev VMs. For production, use autoscale to scale in during low traffic. Finally, monitor egress costs—data transfer out of Azure can be significant.
Disaster Recovery: Backup and Site Recovery
Disaster recovery is not optional. Azure Backup provides simple, automated backups for VMs. Configure daily backups with retention up to 99 years. For cross-region recovery, use Azure Site Recovery (ASR) to replicate VMs to a secondary region. ASR provides continuous replication with RPO of seconds. For production, test your recovery plan regularly—at least quarterly. A common mistake is not testing failover. When a real disaster hits, you'll discover missing dependencies, incorrect network configurations, or insufficient capacity. Use ASR's test failover feature to validate without impacting production. Also, ensure your backup vault and ASR vault are in different regions. For critical databases, consider application-level replication (e.g., SQL Always On) in addition to VM-level backup. Finally, document your RPO and RTO and ensure your solution meets them.
Automation and Infrastructure as Code
Manual VM management is a recipe for disaster. Use Infrastructure as Code (IaC) with ARM templates, Bicep, or Terraform. Define everything: resource group, VNet, subnets, NSGs, VMs, disks, extensions, and monitoring. Store templates in Git and use CI/CD pipelines (Azure DevOps, GitHub Actions) to deploy. For production, use deployment stacks to manage resource lifecycle. A common mistake is using the Azure Portal to make one-off changes—this creates configuration drift. Enforce that all changes go through IaC. Use Azure Policy to audit and enforce compliance (e.g., require tags, enforce disk encryption). For secrets, use Azure Key Vault and reference them in templates. Also, use Azure Blueprints to package policies, RBAC, and resource templates for consistent environments. Finally, automate VM shutdown/startup schedules using Azure Automation or Logic Apps to save costs.
VM Migration and Modernization with Azure Migrate
Migrating on-premises workloads to Azure VMs is one of the most common scenarios. Azure Migrate provides a centralized hub for discovery, assessment, and migration. Use Azure Migrate: Discovery and assessment to inventory your on-premises VMs, dependencies, and performance data. It provides right-sizing recommendations and cost estimates. For actual migration, use Azure Migrate: Server Migration (agentless for VMware, agent-based for other hypervisors). The agentless method replicates VMs without installing software—ideal for large-scale migrations. For database migrations, use Azure Database Migration Service. A common mistake is doing a 'lift and shift' without right-sizing—migrating with the same oversized specs as on-premises. Use the assessment to right-size. Also, test migrations with a pilot group before full cutover. For large-scale migrations (500+ VMs), use Azure Site Recovery for ongoing replication and planned failover. Post-migration, use Azure Advisor to continue optimizing.
Confidential Computing and Sensitive Workloads
For regulated industries handling sensitive data, Azure offers confidential computing VMs that encrypt data in use. DCasv5 and ECasv5 series use AMD SEV-SNP to create trusted execution environments (TEEs). This protects data even from Azure administrators. Use cases include multi-party data analytics, anti-money laundering, and healthcare data processing. For SQL Server, Always Encrypted with secure enclaves leverages confidential computing to process queries on encrypted data. In production, confidential VMs are 10-20% more expensive than standard VMs, but the security benefit justifies the cost for sensitive workloads. Always verify that your operating system and application support confidential computing. For example, Linux kernel 5.19+ is required for AMD SEV-SNP. Also, use Azure Attestation to verify that the TEE is genuine before processing sensitive data.
VM Naming Conventions and Azure VM Families Deep Dive
Azure VM names encode critical information. The format is: Standard_{Family}{Sub-family}{vCPU count}{v}{Version}. For example, Standard_D2s_v5 means D-family (general purpose), 2 vCPUs, s (premium storage capable), v5 (5th generation). Understanding this helps you choose the right VM without memorizing every SKU. General purpose: D-series (balanced), B-series (burstable, credit-based). Compute optimized: F-series (high CPU-to-memory ratio). Memory optimized: E-series (high memory-to-CPU), M-series (very high memory for SAP HANA). Storage optimized: L-series (high disk throughput), NVMe (for databases). GPU: NC, ND, NV (AI/ML, visualization). HPC: HB, HC (high-performance computing). In 2026, the newest generations are v5 (Intel) and v6 (AMD). Always prefer the latest generation for better price-performance. For example, D5 v5 offers ~15% better performance per dollar than D4 v4. Use Azure Pricing Calculator to compare. Also, note that not all VM sizes are available in all regions—use az vm list-skus to check availability.
| File | Command / Code | Purpose |
|---|---|---|
| create-vm.sh | az vm create \ | Azure VMs |
| Get-VMSizes.ps1 | Get-AzVMSize -Location eastus | Where-Object {$_.Name -like "Standard_D*"} | Sel... | Choosing the Right VM Size and Series |
| create-vnet-nsg.sh | az network vnet create \ | Networking |
| Configure-Backup.ps1 | $vault = Get-AzRecoveryServicesVault -ResourceGroupName prod-rg -Name prod-vault | Storage |
| create-vm-zones.sh | for zone in 1 2 3; do | High Availability |
| Create-ScaleSet.ps1 | $vmssConfig = New-AzVmssConfig ` | Scaling |
| install-nginx-extension.sh | az vm extension set \ | Configuration Management with Extensions and Desired State |
| Enable-Monitoring.ps1 | $vm = Get-AzVM -ResourceGroupName prod-rg -Name prod-web-001 | Monitoring and Diagnostics |
| enable-disk-encryption.sh | az vm encryption enable \ | Security |
| Get-CostRecommendations.ps1 | Get-AzAdvisorRecommendation -Category Cost | Where-Object {$_.Impact -eq "High"}... | Cost Management and Right-Sizing |
| Configure-ASR.ps1 | $vault = Get-AzRecoveryServicesVault -ResourceGroupName prod-rg -Name prod-asr-v... | Disaster Recovery |
| vm.bicep | param location string = resourceGroup().location | Automation and Infrastructure as Code |
| assess-migration.sh | az migrate project create \ | VM Migration and Modernization with Azure Migrate |
| create-confidential-vm.sh | az vm create \ | Confidential Computing and Sensitive Workloads |
| check-vm-skus.sh | az vm list-skus --location eastus --size Standard_D --all --output table | VM Naming Conventions and Azure VM Families Deep Dive |
Key takeaways
Interview Questions on This Topic
Explain Virtual Machines and its use cases.
Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
That's Azure. Mark it forged?
8 min read · try the examples if you haven't