Manage Storage for Windows Server Virtual Machines on Azure
Azure Managed Disks and Disk Types
Azure Managed Disks simplify storage management by handling the backend storage accounts for Azure Virtual Machines (VMs). You only specify the required disk size and performance tier, and Azure automatically provisions and manages the underlying resources. This abstraction prevents single storage account limits from impacting multiple virtual disks, improving overall resiliency.
Selecting the right disk tier is critical for balancing performance and cost. Standard HDD works best for backup workloads and non-critical applications where low cost matters more than speed. Standard SSD provides consistent entry-level performance for web servers and light application workloads. Premium SSD delivers high throughput and low latency, making it the preferred choice for mission-critical production workloads. Ultra Disk offers highly scalable performance with sub-millisecond latencies, designed specifically for data-intensive systems like databases.
Configuring disk caching is a key decision for maximizing application performance on Premium SSDs. By default, the operating system disk uses Read-Write caching to speed up system boot and daily operations. For data disks, you must match the cache setting to the specific storage workload.
Choose Read-Only caching for data disks with read-heavy workloads to offload read operations to the VM's local cache. For write-heavy data disks, such as those hosting database transaction logs, select None to disable caching. Disabling caching ensures that write operations go directly to persistent storage, reducing write latency and preventing potential data loss.
High Availability and Sizing
To ensure optimal storage performance, you must match the disk size with the throughput requirements of the workload. When designing for high availability, deploy VMs within availability sets to spread virtual disks across different physical storage units. This architecture minimizes the risk of a single hardware failure bringing down the entire storage cluster.
Migrating to Managed Disks
Migrating existing workloads to managed disks involves uploading virtual hard disks or converting existing unmanaged virtual machines. A virtual hard disk (VHD) can be migrated from on-premises environments or other cloud providers. Before uploading, you must decide whether the VHD is generalized or specialized.
A generalized VHD has been stripped of unique security identifiers and user account information, making it suitable as a reusable template to deploy multiple VMs. A specialized VHD retains its original system settings and user accounts, allowing you to boot the system directly into its original state.
Manage Capacity, Including Resizing and VM Scale Sets
Change the Size of a Virtual Machine (VM)
When a workload needs more CPU, memory, or storage, you can resize an Azure virtual machine to a different size. This process scales the VM up to a larger size or down to a smaller, less expensive one. The key tradeoff is disruption: if the new size is not available on the same physical hardware cluster that hosts the VM, the VM must be deallocated (stopped and released from its host) before the change. Deallocation causes a restart and a brief outage, so it matters for stateful applications that cannot easily stop. When you deallocate a VM, the operating system and data disks are preserved, but any dynamic public or private IP address assigned to the VM is released.
Resizing Methods
You can resize a VM through several tools, each following the same basic lifecycle. In the Azure Portal, you navigate to the virtual machine, select a new size, and apply the change; the portal handles deallocation automatically if needed. With PowerShell, you first run Get-AzVMSize to list the sizes available on the VM's current hardware, then use Update-AzVM to apply the new size. If the desired size is not listed, you must deallocate the VM with Stop-AzVM before resizing. Using the Azure CLI, you check available sizes with az vm list-vm-resize-options, deallocate with az vm deallocate, resize, and then restart the VM. Across all methods, the critical decision point is whether the new size requires a different hardware cluster: if yes, the VM goes through the stopped (deallocated) state and loses its dynamic IP, but keeps its disks and any static IP you assigned.
VM Scale Sets
VM scale sets are groups of identical VMs that work together to handle changes in demand. They keep the application available and cost-efficient by automatically adding or removing instances. Three components make this work:
- Autoscale rules define the conditions that trigger a scale-out (add instances) or scale-in (remove instances), such as average CPU crossing a threshold.
- Load balancing spreads incoming traffic across all healthy instances so that no single VM gets overwhelmed.
- Health probes regularly check each instance; if a VM stops responding, the load balancer stops sending traffic to it, and autoscale rules can replace it.
A scale set depends on the load balancer to distribute requests and on the health probe to detect failure. When demand rises, autoscale adds a new VM. The VM starts in a provisioning state while it is created, then moves to a running state. The load balancer only directs traffic to the VM after the health probe confirms it is healthy. When demand falls, autoscale removes the running instances that have the fewest active connections, following an orderly scale-in policy.
Practical Example: Resizing VMs in an Availability Set
When multiple VMs are grouped in an availability set to protect against hardware failure, you must coordinate the resize operation. First, check if the new size is available on the current hardware using Get-AzVMSize. If it is not available, you must deallocate all VMs in the set at the same time using Stop-AzVM because the entire availability set lives on the same hardware cluster. After they are deallocated, apply the new size to every VM with Update-AzVM, then restart them all with Start-AzVM. This approach prevents a situation where one VM has been resized to a new hardware cluster while another is still on the old cluster, breaking the availability guarantees of the set.
Manage Availability Sets and Availability Zones
Availability Sets Overview
Availability sets are logical groupings of virtual machines (VMs) that help reduce the chances of correlated failures. By distributing VMs across different fault domains, availability sets enhance reliability and are especially useful in Azure regions that do not support availability zones. Placing at least two VMs in an availability set can achieve a 99.95% Azure SLA without additional costs, making this a cost-effective way to meet uptime requirements.
Fault Domains and Update Domains
Within an availability set, Azure separates VMs across different domains to protect against different types of failures. Fault domains group VMs that share common power sources and network switches, and Azure can separate VMs across up to 3 fault domains to limit the impact of physical hardware failures like a power outage or switch failure. Update domains contain VMs and physical hardware that can be restarted together during planned maintenance, and Azure services one update domain at a time so that some VMs stay running while others are updated. This two-domain approach ensures that maintenance or hardware failures do not take all your VMs offline at once.
Availability Zones
Availability zones provide a higher level of reliability by allowing VMs to be deployed across multiple datacenters within the same Azure region. Each zone operates independently with its own power, cooling, and networking, protecting your VMs from localized datacenter failures like a building-wide power outage or network outage. Because the zones are geographically separated within the region, this setup offers stronger resilience compared to availability sets, though it requires support from the specific Azure region you are using.
VM Allocation and Setup
When deploying VMs, you must choose whether to place them in an availability set or across availability zones based on your resiliency needs. For availability sets, you configure the number of fault domains and update domains using Azure CLI or PowerShell to define how Azure spreads your VMs across physical hardware. For availability zone deployments, you specify which zone each VM belongs to, and Azure automatically distributes them across separate datacenters. The choice between these options depends on your SLA requirements, your budget, and whether the Azure region supports availability zones.
Configuring Just-in-Time VM Access
Just-in-Time (JIT) VM Access is a security feature from Microsoft Defender for Cloud that reduces the attack surface of your virtual machines. It works by keeping management ports, like RDP (3389) and SSH (22), closed by default. An administrator must request access, which opens these ports only for a specific IP address and for a limited time window. You configure JIT by selecting target VMs and defining rules that specify which ports can be opened, which source IP ranges are allowed to request access, and the maximum time access can be granted.
Managing JIT Configuration
After JIT is enabled, you can manage its rules. You can add new ports to the policy, modify the list of approved source IP addresses, or adjust the maximum request duration. When a user needs access, they submit a request through the Defender for Cloud portal, selecting the VM, port, their source IP, and a time period within the policy's limits. The port opens only if the request matches all the configured rules, providing precise, temporary access.
Deploying Azure Bastion
Azure Bastion is a fully managed PaaS service that provides secure RDP and SSH connectivity to your VMs without exposing them to the public internet. You connect to a VM through your web browser via the Azure portal, and the traffic flows securely over TLS on port 443. To deploy Bastion, you must first create a dedicated subnet in your virtual network with the specific name AzureBastionSubnet. You then deploy the Bastion resource into this subnet using the Azure portal, CLI, or PowerShell.
Configuring Network Security for Bastion
Because Azure Bastion provides the secure tunnel, your VMs do not need public IP addresses. However, you must configure Network Security Group (NSG) rules to ensure only traffic from the Bastion service can reach your VMs' management ports. This typically involves allowing inbound traffic on ports 3389 (RDP) or 22 (SSH) from the IP range of the AzureBastionSubnet or from the Azure Bastion service tag. This setup creates a clear trust boundary: all administrative traffic must flow through the managed Bastion service, which sits in its own dedicated subnet.
Integrating JIT with Azure Bastion
Using JIT and Azure Bastion together creates a layered security model. You can configure your JIT policy to only allow access requests originating from the IP range used by your Azure Bastion service. This means an administrator must first get JIT approval, which temporarily opens the port, and then they must connect through the Bastion host. This combination enforces that access is both time-limited and channeled through a secure, managed service, validating connectivity without any public IP exposure on the VMs themselves.