Skip to main content

Theoretical Foundation: Create a Virtual Machine


1. Initial Intuition​

Imagine you need a server to run an application. In the physical world, you would buy hardware, install the operating system, configure the network, and wait days or weeks until everything is ready. In Azure, you describe the server you want (how many CPU cores, how much memory, which operating system, which region of the world) and in minutes it's available.

A Virtual Machine (VM) in Azure is a complete computer running on Microsoft's shared hardware, isolated from other customers through virtualization technology. From the operating system and application perspective, the VM looks like a dedicated physical server. You have complete control: install software, configure services, access the terminal.

The fundamental difference compared to managed services like App Service or Azure Functions is that with VMs you manage the operating system: you're responsible for patches, security updates, and internal configuration.


2. Context​

2.1 VMs in the IaaS model​

Azure offers different levels of abstraction. VMs are at the IaaS (Infrastructure as a Service) level: you manage from the operating system up; Microsoft manages the physical hardware, physical network, and hypervisor.

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

2.2 Use cases that require VMs​

VMs are the right choice when:

  • The application wasn't developed for cloud and can't be easily refactored
  • You need complete control over the operating system (specific patches, kernel configurations)
  • The software requires traditional installation (agents, legacy middleware)
  • You're migrating on-premises workloads via lift-and-shift
  • The workload requires specific hardware (GPU, HPC)

3. Building the Concepts​

3.1 Resources created along with the VM​

When you create a VM in Azure, the portal automatically creates a set of related resources. Understanding each one is essential for properly managing VMs:

Virtual Machine: The main resource. Represents the compute configuration (CPU, memory, size).

Disk (OS Disk): Every VM has at least one managed disk that contains the operating system. Created automatically.

Network Interface (NIC): The VM's "virtual network card". Connects the VM to the VNet. Has a private IP and optionally a public IP.

Virtual Network (VNet) and Subnet: The private network where the VM lives. Can be created automatically or use an existing VNet.

Network Security Group (NSG): Virtual firewall associated with the NIC or subnet. Controls inbound and outbound traffic.

Public IP Address (optional): Public IP for direct access via internet. Can be static or dynamic.

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

3.2 VM family and size​

The VM size defines CPU, memory, temporary disk, and network capacity. Sizes are organized in series (families), each optimized for a type of workload:

FamilyPrefixOptimized for
General PurposeB, D, Dv5, Dav5Balanced workloads (web, dev, test)
Compute OptimizedF, FxHigh CPU/memory ratio (data processing)
Memory OptimizedE, Ev5, MIn-memory databases, SAP HANA
Storage OptimizedLsv3High disk I/O databases
GPUNC, ND, NVMachine Learning, 3D rendering
High Performance ComputeHScientific simulations, CFD
BurstableBWorkloads with variable CPU usage

The size naming follows a pattern:

Standard_D4s_v5
β”‚ β”‚ β”‚
β”‚ β”‚ └── version (v5 = fifth generation)
β”‚ └───── s = Premium SSD support
└─────── number of vCPUs

3.3 Images: the operating system​

An image is the disk template used to create the VM. Azure Marketplace offers thousands of images, including:

First-party images (Microsoft):

  • Windows Server 2022, 2019, 2016
  • Windows 11 Enterprise (for VDI)

Third-party images (certified):

  • Ubuntu 22.04, 20.04, 18.04
  • Red Hat Enterprise Linux 8, 9
  • CentOS, Debian, SUSE
  • SQL Server on Windows/Linux
  • Oracle Database

Custom images: You can create your own image from a configured VM (via Azure Compute Gallery).


3.4 Disks: types and performance​

Azure offers different types of managed disks with different performance and cost characteristics:

TypeUseMax IOPSLatencyCost
Ultra DiskCritical databasesUp to 400,000Sub-millisecondHighest
Premium SSD v2I/O intensive workloadsUp to 80,000~1msHigh
Premium SSDGeneral productionUp to 20,000~1-2msMedium-high
Standard SSDWeb servers, devUp to 6,000~2-10msMedium
Standard HDDBackup, filesUp to 2,000~5-50msLow

Temporary Disk: In addition to managed disks, VMs have a temporary disk (D: on Windows, /dev/sdb on Linux) that doesn't persist after deallocation or resizing. Never store permanent data on it.


3.5 Availability options​

VM availability depends on how you organize them. Azure offers three mechanisms:

Availability Set:

  • Distributes VMs across Fault Domains (different physical racks) and Update Domains (sequential update groups)
  • Protects against hardware failures and Azure maintenance
  • 99.95% SLA for two or more VMs in the same Availability Set

Availability Zone:

  • Distributes VMs across physically separate datacenters within a region
  • Protects against entire datacenter failure
  • 99.99% SLA for two or more VMs in different zones

Virtual Machine Scale Sets:

  • Creation and management of multiple identical VMs (horizontal scale)
  • Auto-scaling based on metrics
  • Covered in separate AZ-104 objectives

Isolated VM (no option):

  • 99.9% SLA (only for VMs with Premium SSD)
  • Suitable only for development and testing

3.6 Licensing and cost options​

Pay-as-you-go: Pay per hour of use. More expensive per hour, but no commitment.

Reserved Instances (RI): 1 or 3-year commitment in exchange for up to 72% discount. For predictable workloads.

Azure Hybrid Benefit: If you have Windows Server or SQL Server licenses with active Software Assurance, you can bring those licenses to Azure, saving the license cost in the VM price.

Spot VMs: Azure's excess capacity at very low prices (up to 90% discount), but the VM can be removed with 30 seconds notice when Azure needs the capacity. Suitable for interruption-tolerant workloads (batch processing, rendering).


4. Structural View​

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

Critical behavior: Stopping the VM from the operating system ("shutdown" within the OS) puts the VM in Stopped state, but doesn't deallocate. You continue paying for compute allocation. To stop compute billing, use Deallocate through portal, CLI, or PowerShell.


5. Practical Operation​

5.1 Information needed to create a VM​

Before creating, you need to decide:

DecisionOptionsImpact
Regioneastus, westeurope, brazilsouth, etc.Latency, data compliance, size availability
Operating systemWindows Server, Linux (Ubuntu, RHEL, etc.)License cost, management
Size (SKU)Standard_D2s_v5, Standard_B2ms, etc.Performance and cost
AuthenticationPassword or SSH key (Linux)Security
VNet/SubnetNew or existingConnectivity
Public IPNone, dynamic or staticRemote access
OS diskPremium SSD, Standard SSD, Standard HDDPerformance and cost
AvailabilityZone, Availability Set, noneResilience

5.2 Cloud-init and Custom Script Extension​

To configure the VM automatically during creation without manual interaction, Azure supports:

cloud-init (Linux): YAML or bash script executed on first boot. Ideal for installing packages, configuring services, and running commands.

#cloud-config
package_upgrade: true
packages:
- nginx
- docker.io
runcmd:
- systemctl enable nginx
- systemctl start nginx

Custom Script Extension (Windows and Linux): Script executed after the VM is ready. Can be PowerShell (Windows) or bash (Linux). Can be referenced from a Storage Account or provided inline.


6. Implementation Methods​

6.1 Azure Portal​

When to use: Single creation, learning, when visual exploration of options is necessary.

In portal: Virtual Machines > + Create > Azure Virtual Machine

The portal guides through tabs: Basics, Disks, Networking, Management, Monitoring, Advanced, Tags.

Advantages: Immediate visualization of all parameters, real-time validation, option to see generated ARM template.

Limitation: Not consistently reproducible; slow for multiple VMs.


6.2 Azure CLI​

Basic Linux VM creation:

az vm create \
--resource-group myRG \
--name myLinuxVM \
--image Ubuntu2204 \
--size Standard_D2s_v5 \
--location eastus \
--admin-username azureuser \
--generate-ssh-keys \
--vnet-name myVNet \
--subnet mySubnet \
--public-ip-sku Standard \
--nsg-rule SSH

Windows VM creation:

az vm create \
--resource-group myRG \
--name myWindowsVM \
--image Win2022Datacenter \
--size Standard_D4s_v5 \
--location eastus \
--admin-username adminuser \
--admin-password "MySecureP@ss123!" \
--nsg-rule RDP \
--public-ip-sku Standard

Creation with Availability Zone:

az vm create \
--resource-group myRG \
--name myVM-Zone1 \
--image Ubuntu2204 \
--size Standard_D2s_v5 \
--zone 1 \
--admin-username azureuser \
--generate-ssh-keys

Creation with cloud-init:

az vm create \
--resource-group myRG \
--name myWebServer \
--image Ubuntu2204 \
--size Standard_D2s_v5 \
--admin-username azureuser \
--generate-ssh-keys \
--custom-data @cloud-init.yaml

Lifecycle operations:

# Stop and deallocate (stops compute billing)
az vm deallocate --resource-group myRG --name myVM

# Start
az vm start --resource-group myRG --name myVM

# Restart
az vm restart --resource-group myRG --name myVM

# Resize (change SKU)
az vm resize --resource-group myRG --name myVM --size Standard_D4s_v5

# View current state
az vm show --resource-group myRG --name myVM --show-details --query powerState

6.3 Azure PowerShell​

# Create complete VM
$vmConfig = New-AzVMConfig `
-VMName "myVM" `
-VMSize "Standard_D2s_v5"

# Configure OS
$vmConfig = Set-AzVMOperatingSystem `
-VM $vmConfig `
-Linux `
-ComputerName "myVM" `
-Credential (Get-Credential)

# Specify image
$vmConfig = Set-AzVMSourceImage `
-VM $vmConfig `
-PublisherName "Canonical" `
-Offer "0001-com-ubuntu-server-jammy" `
-Skus "22_04-lts-gen2" `
-Version "latest"

# Add NIC
$nic = Get-AzNetworkInterface -Name "myNIC" -ResourceGroupName "myRG"
$vmConfig = Add-AzVMNetworkInterface -VM $vmConfig -Id $nic.Id

# Create the VM
New-AzVM `
-ResourceGroupName "myRG" `
-Location "eastus" `
-VM $vmConfig

6.4 Bicep​

// Linux VM with all components
resource vm 'Microsoft.Compute/virtualMachines@2023-07-01' = {
name: 'myLinuxVM'
location: location
properties: {
hardwareProfile: {
vmSize: 'Standard_D2s_v5'
}
storageProfile: {
imageReference: {
publisher: 'Canonical'
offer: '0001-com-ubuntu-server-jammy'
sku: '22_04-lts-gen2'
version: 'latest'
}
osDisk: {
createOption: 'FromImage'
managedDisk: {
storageAccountType: 'Premium_LRS'
}
deleteOption: 'Delete'
}
}
osProfile: {
computerName: 'myLinuxVM'
adminUsername: 'azureuser'
linuxConfiguration: {
disablePasswordAuthentication: true
ssh: {
publicKeys: [
{
path: '/home/azureuser/.ssh/authorized_keys'
keyData: sshPublicKey
}
]
}
}
}
networkProfile: {
networkInterfaces: [
{
id: nic.id
properties: {
deleteOption: 'Delete'
}
}
]
}
availabilitySet: {
id: availabilitySet.id
}
}
zones: ['1']
}

deleteOption: The deleteOption: 'Delete' property on disks and NICs ensures that when the VM is deleted, associated resources are also deleted automatically. Without this, "orphaned" disks and NICs continue to exist and be charged.


7. Control and Security​

7.1 Authentication: SSH Keys vs Password​

For Linux VMs: Always use SSH keys in production. Passwords are more vulnerable to brute force attacks.

# Generate SSH key pair locally
ssh-keygen -t rsa -b 4096 -f ~/.ssh/myVM_key

# Public key goes to VM; private key stays on local machine
# Connect via SSH
ssh -i ~/.ssh/myVM_key azureuser@<public-ip>

For Windows VMs: Use strong passwords with:

  • Minimum 12 characters
  • Uppercase, lowercase, numbers, and symbols
  • Don't use common passwords

Azure Key Vault: Store SSH keys and administrator passwords in Azure Key Vault. Avoid storing them in code or repositories.


7.2 RBAC permissions for VMs​

RolePermissionsUse
Virtual Machine ContributorManage VMs but not VNets and storage accountsCompute administrators
Virtual Machine Administrator LoginLogin to VM as admin via Azure ADPrivileged access
Virtual Machine User LoginLogin to VM as standard user via Azure ADUser access
ReaderView configurationsMonitoring

Azure AD Login for VMs: With the AADSSHLoginForLinux or AADLoginForWindows extension, users can login to the VM with their Azure AD credentials, without managing local users.


7.3 JIT (Just-in-Time) VM Access​

Microsoft Defender for Cloud offers JIT: management ports (22, 3389) remain closed by default and are opened temporarily only when requested, for the specific requester's IP, for the determined time.

# Enable JIT via CLI
az security jit-policy create \
--resource-group myRG \
--vm-ids <vm-resource-id> \
--name "default" \
--ports '[{"number":22,"protocol":"TCP","allowedSourceAddressPrefix":"*","maxRequestAccessDuration":"PT3H"}]'

8. Decision Making​

8.1 Which VM size to choose​

WorkloadRecommended FamilyExample
Web server, dev/testGeneral PurposeStandard_D2s_v5
Database serverMemory OptimizedStandard_E4s_v5
Data processing, analyticsCompute OptimizedStandard_F4s_v2
High I/O databaseStorage OptimizedStandard_L8s_v3
ML trainingGPUStandard_NC6s_v3
Variable workloads (dev, CI/CD)BurstableStandard_B2ms

8.2 Which disk type to choose​

SituationDisk typeReason
Production databasePremium SSD v2 or Ultra DiskHigh IOPS, minimal latency
Production web serverPremium SSDGood performance, adequate SLA
Development serverStandard SSDReduced cost, SSD
Backup, archiveStandard HDDLowest cost
Temporary disk for processingTemporary Disk (careful!)Free, but not persistent

8.3 Static vs dynamic public IP​

SituationChoiceReason
DNS pointing to VMStatic public IPIP doesn't change after reboot
VM with Bastion (no direct access)No public IPAccess via Bastion, no exposure
Temporary development environmentDynamic public IPLower cost
Production server with external accessStatic public IP + Azure Firewall or LBStability and protection

8.4 Availability Set vs Availability Zone​

RequirementChoiceSLA
No HA requirementNone99.9%
HA within single datacenterAvailability Set99.95%
HA across region datacentersAvailability Zone99.99%
Maximum resilienceVMs in multiple regions + Traffic Manager> 99.99%

9. Best Practices​

  • Use deleteOption: Delete for disks and NICs when creating VMs via IaC. This prevents orphaned resources when the VM is deleted.
  • Never open SSH/RDP directly from the internet. Use Azure Bastion, JIT, or VPN.
  • Use SSH keys for Linux VMs in production, never passwords.
  • Enable Azure AD Login to eliminate local user management and leverage MFA and Conditional Access.
  • Use Managed Disks (current standard) instead of unmanaged disks (legacy).
  • Specify availability zone for production VMs in regions that support Availability Zones.
  • Use Reserved Instances for workloads that will run for 1 year or more.
  • Enable Azure Monitor and configure CPU, memory, and disk alerts from the start.
  • Use tags to identify environment (prod, dev, test), application, responsible team, and cost center.
  • Don't store data on temporary disk. Use managed data disks for persistent data.
  • Use Azure Hybrid Benefit if you have active Windows Server or SQL Server licenses.

10. Common Errors​

ErrorWhy it happensHow to avoid
VM "stopped" but still chargingStopped by OS, not deallocatedUse az vm deallocate or portal to deallocate
Orphaned disk and NIC after deleting VMdeleteOption not configuredSet deleteOption: Delete on creation or delete manually
Can't connect via SSH/RDPNSG blocking port 22/3389Check NSG inbound rules
Public IP changes after rebootDynamic IP used where static was neededConvert to static public IP
Wrong VM size chosenDidn't consider workload requirementsSize based on expected CPU, memory, and IOPS
Admin password forgotten (Windows)Not documented or storedUse Azure AD Login or reset via Run Command
VM without monitoring configuredForgot to enable during creationEnable Azure Monitor Agent after creation
Spot VM removed without sufficient warningWorkload not tolerant to interruption on SpotUse Spot only for tolerant workloads (batch, render)

11. Operation and Maintenance​

11.1 VM Monitoring​

Azure Monitor VM Insights: Collects CPU, memory, disk, and network metrics with ready-made visualizations.

# Enable Azure Monitor Agent on VM
az vm extension set \
--resource-group myRG \
--vm-name myVM \
--name AzureMonitorLinuxAgent \
--publisher Microsoft.Azure.Monitor \
--version 1.0

Important metrics:

MetricAlert thresholdWhat it indicates
CPU Percentage> 80% for 5 minNeed for resize or optimization
Available Memory Bytes< 10%Memory pressure
OS Disk Queue Depth> 10Disk bottleneck
Network In/OutAbnormal spikeSuspicious traffic or saturation

11.2 VM Resizing​

# List available sizes in region for resizing
az vm list-vm-resize-options \
--resource-group myRG \
--name myVM \
--output table

# Resize (requires stop and restart)
az vm resize \
--resource-group myRG \
--name myVM \
--size Standard_D4s_v5

Resizing requires VM restart (downtime). Plan maintenance windows.


11.3 Run Command: execute scripts without SSH/RDP​

If you lost SSH/RDP access, Run Command allows executing scripts on the VM via portal or CLI:

# Execute bash script on Linux VM
az vm run-command invoke \
--resource-group myRG \
--name myVM \
--command-id RunShellScript \
--scripts "echo 'Hello World' && systemctl status nginx"

# Reset admin password (Windows)
az vm user reset-ssh \
--resource-group myRG \
--name myVM

11.4 Important limits​

ResourceDefault limit
VMs per region per subscription10,000 vCPUs (increasable)
Data disks per VMDepends on size (D2s_v5: up to 4; D64s_v5: up to 32)
NICs per VMDepends on size
Private IPs per NICUp to 30
VMs in Availability SetUp to 200
Fault Domains per Availability Set2 or 3 (region dependent)

12. Integration and Automation​

12.1 VM Extensions​

Extensions are agents installed on the VM that execute automated tasks:

# Install Custom Script extension (run script after creation)
az vm extension set \
--resource-group myRG \
--vm-name myVM \
--name CustomScript \
--publisher Microsoft.Azure.Extensions \
--settings '{"commandToExecute":"apt-get install -y nginx"}'

# List installed extensions
az vm extension list \
--resource-group myRG \
--vm-name myVM \
--output table

Common extensions:

ExtensionFunction
CustomScriptExecutes custom scripts
AzureMonitorLinuxAgentCollects metrics and logs
DependencyAgentMaps network dependencies (VM Insights)
AADSSHLoginForLinuxAzure AD login on Linux
AADLoginForWindowsAzure AD login on Windows
MicrosoftAntiMalwareAntimalware protection (Windows)

12.2 Azure Automation with VMs​

To automatically shutdown VMs outside business hours:

# Configure auto-shutdown via CLI
az vm auto-shutdown \
--resource-group myRG \
--name myVM \
--time 2200 \
--email "admin@company.com"

For more complex automation (start VMs before hours, process multiple VMs), use Azure Automation Runbooks or Azure Functions with schedule trigger.


12.3 Azure Policy for VM compliance​

# Ensure all VMs use mandatory tags
az policy assignment create \
--name "vm-require-tags" \
--policy "96670d01-0a4d-4649-9c89-2d3abc0a5025" \
--scope "/subscriptions/<sub-id>"

# Audit VMs without Azure Monitor Agent
az policy assignment create \
--name "vm-require-monitoring" \
--policy "5641f9d1-f911-4988-abf4-92c8e0f2af0a" \
--scope "/subscriptions/<sub-id>"

13. Final Summary​

Essential concepts:

  • An Azure VM is a complete virtual computer (IaaS) where you control the operating system and everything above it.
  • When creating a VM, Azure automatically creates: OS disk, NIC, and optionally public IP, NSG, VNet and subnet.
  • The size defines CPU, memory and disk capacity. Choose based on workload: General Purpose, Memory Optimized, Compute Optimized, GPU, etc.
  • The Stopped state β‰  Deallocated: only Deallocated stops compute billing.

Critical differences:

  • Stopped vs Deallocated: Stopped = OS shut down but hardware still allocated (charges compute). Deallocated = hardware released (charges only storage).
  • Availability Set vs Availability Zone: Set distributes across racks in same datacenter (99.95%). Zone distributes across datacenters (99.99%).
  • Dynamic vs static IP: Dynamic changes when deallocated. Static remains. Use static when DNS or firewall depends on IP.
  • Temporary disk vs data disk: Temporary doesn't persist after deallocation. Managed data disk always persists.

What needs to be remembered:

  • Use deleteOption: Delete for disks and NICs to avoid orphaned resources.
  • Never open SSH/RDP ports directly from internet. Use Bastion or JIT.
  • The temporary disk is on D: on Windows and /dev/sdb or /mnt on Linux, and doesn't persist data after deallocation.
  • Azure Hybrid Benefit can significantly reduce Windows and SQL Server VM costs.
  • Use Reserved Instances for workloads that will run for 1 year or more; savings can reach 72%.
  • Spot VMs are economical but can be removed anytime with 30 seconds notice.
  • Run Command allows executing scripts on VM without direct SSH/RDP access, useful for access recovery.