Archive for March, 2019

Resizing managed VM disks in Azure

Executive summary:

  • As of 7 March 2019,¬†Microsoft allows resizing data and OS managed disks up via PowerShell and the Azure Portal
  • Microsoft does not allow resizing managed disks down
  • Disk resizing requires VM shutdown and restart

Microsoft charges for the entire amount of allocated disk space of managed disks.

Also see the example in this post.

This is a major difference compared to unmanaged disks where Microsoft charges only for used disk space. IT professionals now have to walk a tight rope in terms of disk capacity in Azure. On one hand you need a minimum amount of free disk space on each disk to guard against running out of disk space scenarios, on the other hand you need to keep the overall disk size as small as possible to avoid the high disk cost. Currently Microsoft charges for managed disk capacity as follows (East US, standard LRS)

For example, if we have a VM with 100 GB data disk – 50 GB are used, we’re billed for S10 which is the next size up in the amount of $5.89/month.

As data grows over time, we may need to expand this disk. We can resize a managed data disk using Powershell as follows:

First we declare the needed variables, and authenticate to our Azure subscription:

#Requires -Version 5
#Requires -Modules AzureRM,AZSBTools

# Install-Module AZSBTools

$LoginName           = ''
$SubscriptionName    = 'my subscription name'
$Location            = 'EastUS'
$UseCase             = 'TestMD2'

$VMParameterList = @{
    Name                = "$UseCase-VM"
    ResourceGroupName   = "$UseCase-RG"
    Location            = $Location
    VirtualNetworkName  = "$UseCase-Vnet"
    SubnetName          = "$UseCase-Subnet"
    PublicIpAddressName = "$UseCase-PiP"
    OpenPorts           = @(80,3389)
    Credential          = (Get-SBCredential 'myVMAdmin') 
    Size                = 'Standard_D1_v2'       # Get-AzureRmVMSize -Location $Location
    DataDiskSizeInGb    = 128 

Login-AzureRmAccount -Credential (Get-SBCredential $LoginName) | Out-Null # -Environment AzureCloud 
Get-AzureRmSubscription -SubscriptionName $SubscriptionName -WA 0 | 
    Set-AzureRmContext | Out-Null 

Next we provision our test VM:

$Duration = Measure-Command { $VM = New-AzureRmVM @VMParameterList }
Write-Log 'Done in',"$($Duration.Hours):$($Duration.Minutes):$($Duration.Seconds) hh:mm:ss" Green,Cyan
Write-Log ' OS Disk (Managed): size',"$($VM.StorageProfile.OsDisk.DiskSizeGB) GB",'- Underlying storage',$VM.StorageProfile.OsDisk.ManagedDisk.StorageAccountType Green,Cyan,Green,Cyan
$VM.StorageProfile.DataDisks | foreach { 
    Write-Log ' Data Disk (Managed): Lun',$_.Lun,'- size',"$($_.DiskSizeGB) GB" Green,Cyan,Green,Cyan

and we get output like:

Next we RDP to the test VM and write test data to the data disk:

$IPv4Address = (Get-AzureRmPublicIpAddress -ResourceGroupName $VM.ResourceGroupName -Name "$UseCase-PiP").IpAddress  
mstsc /v:$IPv4Address

After login to the VM, we partition and format the data disk:

and write test data to drive f:

Back in Powershell, we resize the data disk. This requires stopping the VM and starting it back up:

$DataDisk = Get-AzureRmDisk -ResourceGroupName $VM.ResourceGroupName -DiskName $VM.StorageProfile.DataDisks[0].Name
Write-Log 'Data disk size:',"$($DataDisk.DiskSizeGB) GB",'stopping VM..' Green,Cyan,Green -NoNew
$VM | Stop-AzureRmVM -Force | Out-Null
do { Start-Sleep -Seconds 10 } while (
    (Get-AzureRmVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -Status).Statuses[1].DisplayStatus -ne 'VM deallocated'
Write-Log 'Done' Cyan
Write-Log 'Resizing disk',$VM.StorageProfile.DataDisks[0].Name,'to 250 GB' Green,Cyan,Green -NoNew
New-AzureRmDiskUpdateConfig -DiskSizeGB 250 | Update-AzureRmDisk -ResourceGroupName $VM.ResourceGroupName -DiskName $VM.StorageProfile.DataDisks[0].Name
Write-Log 'Done' Cyan
$DataDisk = Get-AzureRmDisk -ResourceGroupName $VM.ResourceGroupName -DiskName $VM.StorageProfile.DataDisks[0].Name
Write-Log 'New data disk size:',"$($DataDisk.DiskSizeGB) GB" Green,Cyan
Write-Log 'Starting VM',$VM.Name Green,Cyan -NoNew
$VM | Start-AzureRmVM | Out-Null
Write-Log 'Done' Green
mstsc /v:$IPv4Address

and we get output like

Back in the VM we see the new disk size:

We extend the volume to use all provisioned space:

And validate the data.

We cannot however use the same process in reverse to down size a disk.

We can resize the volume down inside the VM:

In Computer Management/Disk Management, we shrink the volume down to 60 GB

Note: To reduce storage cost, shrink the volume to a size that’s just below a billing size. The current billing disk sizes are 32 GB, 64 GB, 128 GB, 256 GB, 512 GB, 1 TB, 2 TB, 4 TB, 8 TB, 16 TB, and 32 TB

Shrinking the disk in Windows:

Back in PowerShell, after shutting down and deallocating the VM, if we try resize the disk down:

We can also resize the OS disk up but not down: