In my last blog post I shared about how I use a Microsoft Azure Virtual Machine as my development machine. It’s been a month since I made this drastic change, and I must admit that it’s been pretty cool! The Azure Virtual Machine has provided me with more agility in my hectic schedule. I’ve been able to start my day from one machine, move to a different machine and continue from where I left off. I no longer deal with putting my machine to sleep or trying to remember where I was when I left off. When I log off from one machine, I log back in right where I left off.

It’s Getting Tight

As I move from project to project, the resource requirements vary, and sometimes I need more resources. Fortunately, we can scale our Virtual Machines up and down through PowerShell and the Azure Portal. I usually work with a Standard D2 Virtual Machine, that translates to 2 Cores 7 GB of RAM and a 100GB SSD Temp Disk. On some occasions, I scale-up to a Standard D4, that translates to 8 Cores 28GB of RAM and a 400GB SSD Temp Disk.

$serviceName = 'mydevmachine'
$name = 'mydevmachine'

# Stop the Azure VM
Stop-AzureVM -Name $name -ServiceName $serviceName -Force

# Get a reference to the Azure VM
$vm = Get-AzureVM -Name $name -ServiceName $serviceName

# Wait for the VM to reach the StoppedDeallocated State
Write-Output $('VM state is '+ $vm.InstanceStatus)

while( $vm.InstanceStatus -ne 'StoppedDeallocated')
{
    Start-Sleep -s 10
    $vm = Get-AzureVM -Name $name -ServiceName $serviceName
    Write-Output $('VM state is '+ $vm.InstanceStatus)
}

# Set the Instance Size & Update the WM
Set-AzureVMSize -InstanceSize Standard_D4 -VM $vm | Update-AzureVM

# Start the Azure VM
Start-AzureVM -Name $name -ServiceName $serviceName

# Wait for the VM to reach the ReadyRole State
$vm = Get-AzureVM -Name $name -ServiceName $serviceName
Write-Output $('VM state is '+ $vm.InstanceStatus)

while( $vm.InstanceStatus -ne 'ReadyRole')
{
    Start-Sleep -s 10
    $vm = Get-AzureVM -Name $name -ServiceName $serviceName
    Write-Output $('VM state is '+ $vm.InstanceStatus)
}

# VM Boot Grace Period
Start-Sleep -s 60

# Download and launch a Remote Desktop Session to the resized Azure VM
Get-AzureRemoteDesktopFile -Name $name -ServiceName $serviceName -Launch

UH OH!

The instance size we are looking for isn’t available? Don’t worry about it just yet. Not all Azure server racks are created equal. This means that if the Virtual Machine was initially created as a Standard A1, the configurations we are looking for might not be available. Consequentially, scaling to a newer Virtual Machine configuration requires us to take a different approach. First off, let’s find out if the Virtual Machine Instance Size is available in our Data Center.

Get-AzureLocation `
 | Where-Object {$_.VirtualMachineRoleSizes -contains 'A9'} `
 | Select-Object -Property Name

Name
----
South Central US
West US
East US
North Europe
West Europe
Japan East

If for some reason, the Data Center doesn’t have the desired Virtual Machine Instance Size available. We can review the list of Instance Sizes for a specific Data Center. Then we can decide whether we want to migrate to another Data Center or chose to use a different Virtual Machine Instance Size.

Get-AzureLocation `
| Where-Object -Property Name -EQ 'East US 2' `
| Select-Object -ExpandProperty VirtualMachineRoleSizes

A5
A6
A7
Basic_A0
Basic_A1
Basic_A2
Basic_A3
Basic_A4
ExtraLarge
ExtraSmall
Large
Medium
Small
Standard_D1
Standard_D11
Standard_D12
Standard_D13
Standard_D14
Standard_D2
Standard_D3
Standard_D4
Standard_DS1
Standard_DS11
Standard_DS12
Standard S_DS13
Standard_DS14
Standard_DS2
Standard_DS3
Standard_DS4
Standard_G1
Standard_G2
Standard_G3
Standard_G4
Standard_G5

As of April 30th 2015, the East US 2 Data Center has the D, DS and G Series but it does not have A8, A9, A10 or A11 Virtual Machine configurations. Scaling to A9 Virtual Machine, that translates to 16 Cores 112 GB of RAM, 382GB Temp Disk, 40Gbit/s InfiniBand network and remote direct memory access (RDMA) would require me to move my Virtual Machine to the East US Data Center.

It’s Time to Move

The first step towards moving, is to capture an Image of the Virtual Machine that we want to move. Before we start, be sure that the Virtual Machine is in a StoppedDeallocated state.

$servicename = "mydevmachine"
$vmname = "mydevmachine"

Get-AzureVM -ServiceName $servicename `
            -Name $vmname `
| Stop-AzureVM -Force

Then capture the Virtual Machine Image and give it a meaningful name

Save-AzureVMImage –ServiceName $servicename `
                  –Name $vmname `
                  –ImageName "BriseboisDevMachine" `
                  –OSState "Specialized" `
                  -Verbose

Create a Storage Account Context

# Source Storage Account Context
$sourceStorageAccountName = "briseboisms1"
$sourceKey = (Get-AzureStorageKey -StorageAccountName $sourceStorageAccountName).Primary
$sourceContext = New-AzureStorageContext –StorageAccountName $sourceStorageAccountName `
                                         -StorageAccountKey $sourceKey

Then find the VHD created by the Save-AzureVMImage cmdlet.

Get-AzureStorageBlob -Container 'vhds' -Context $sourceContext

Container Uri: https://briseboisms.blob.core.windows.net/vhds

Name                                   BlobType  Length        ContentType              LastModified                 SnapshotTime
----                                   --------  ------        -----------              ------------                 ------------
BriseboisDevMachine-os-2015-04-30.vhd  PageBlob  136367309312  application/octet-stream 4/30/2015 9:58:31 PM +00:00

Create a Storage Account in the Data Center that has the desired Virtual Machine Instance Size.

$destinationStorageAccountName = 'briseboisuseast1'

New-AzureStorageAccount -StorageAccountName $destinationStorageAccountName `
                        -Location 'East US' `
                        -Type 'Standard_GRS'

Copy the VHD created by the Save-AzureVMImage cmdlet to the newly Storage Account.

$blobName = 'BriseboisDevMachine-os-2015-04-30.vhd'
$container = 'vhds'

# Destination Storage Account Contex
$destinationKey = (Get-AzureStorageKey -StorageAccountName $destinationStorageAccountName).Primary
$destinationContext = New-AzureStorageContext –StorageAccountName $destinationStorageAccountName `
                                              -StorageAccountKey $destinationKey  

# Create the destination container
New-AzureStorageContainer -Name $container `
                          -Context $destinationContext 

# Copy the blob
$blobCopy = Start-AzureStorageBlobCopy -DestContainer $container `
                                       -DestContext $destinationContext `
                                       -SrcBlob $blobName `
                                       -Context $sourceContext `
                                       -SrcContainer $container

# Blob Copy Progress
while(($blobCopy | Get-AzureStorageBlobCopyState).Status -eq "Pending")
{
    Start-Sleep -s 30
    $blobCopy | Get-AzureStorageBlobCopyState
}

Now it’s time to re-hydrate the Virtual Machine with the desired Instance Size

# Add the Captured Virtual Machine as a VM Image
Add-AzureVMImage -ImageName BriseboisDevMachineEast `
                 -OS Windows `
                 -MediaLocation "https://$destinationStorageAccountName.blob.core.windows.net/vhds/$blobName"

# Verify that the VM Image has been added as expected
Get-AzureVMImage | Where-Object {$_.Location -eq 'East US'} `
                 | Where-Object {$_.ImageName -eq 'BriseboisDevMachineEast'} `
                 | Select-Object { $_.ImageName , $_.Location }

# Switch the CurrentStorageAccount to the destination Storage Account
Set-AzureSubscription -SubscriptionName 'Visual Studio Ultimate with MSDN' `
                      -CurrentStorageAccountName $destinationStorageAccountName

# Create the Virtual Machine using the newly created VM Image
New-AzureQuickVM -Windows `
-ServiceName BriseboisDev `
-Name BriseboisDev `
-ImageName BriseboisDevMachineEast `
-InstanceSize 'A9' `
-Password 'MY-PASSWORD' `
-Location 'East US' `
-AdminUsername 'MY-USERNAME' `
-Verbose

Once the Virtual Machine is running, we can RDP into it and resume our operations.

# Download and Launch RDP file for the new Azure VM
Get-AzureRemoteDesktopFile -ServiceName BriseboisDevMachineEast `
                           -Name BriseboisDevMachineEast `
                           -Launch

Note

Creating Larger Virtual Machines may take more time than what you would expect for smaller Virtual Machine Instance Sizes. This is because Azure has to find a location with enough resources to provision the instance. If you shut down a large Virtual Machine, you may encounter a situation where the Azure fabric is unable to start the Virtual Machine. One way to solve this, is to re-size the Virtual Machine by using a technique similar with the one found in the first section of this post. This will result in Azure to create an instance in a rack that has enough resources to meet the Virtual Machine Instance Size requirements.

Resources

3 responses to Sometimes You Just Have to Scale Up!

  1. 

    Awesome tutorial again from Alexandre, that put together a very useful script for us. Suggestion of the week on Reading Notes #184 http://www.frankysnotes.com/2015/05/reading-notes-184.html

    Like

  2. 

    Yup one of many interesting blogs Alexandre has written. A must read for the Azure noobs like me.

    Like

Trackbacks and Pingbacks:

  1. Dew Drop – May 4, 2015 (#2006) | Morning Dew - May 4, 2015

    […] Sometimes You Just Have to Scale Up! (Alexandre Brisebois) […]

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.