Background
We are implementing Azure solutions for a few clients. Most of our clients are use cloud services and virtual machines to implement their solutions on Azure platform. For many years Azure platform only offered just one performance tier for storage. You can see the sizes of virtual machines and cloud services and the disk performance they offer here:
https://msdn.microsoft.com/en-us/library/azure/dn197896.aspx
For standard Azure virtual machines each disk is limited to 500 IOPS per disk. If you needed better performance you had to use disk striping with multiple disk to get better performance. Number of disks one could add to Azure Virtual Machine is constrained by the size of VM. One core allows us to add 2 VHD’s. Each VHD is a page blob with a maximum size of 1 TB. When we were deploying packaged software or custom applications with high IOPS requirements it was challenging to meet the needs of our customers. All this changed with the following announcement by Mark Russinovich where he announced General Availability of Azure Premium Storage.
http://azure.microsoft.com/blog/2015/04/16/azure-premium-storage-now-generally-available-2/
Azure premium storage offers durable SSD storage. Along with premium storage Microsoft also released storage optimized virtual machines called DS Series VM’s. These are capable of achieving up to 64000 IOPS and 524 MB/sec. This will enable many scenarios like NoSQL or even large SQL database that need higher IOPS than the standard Azure virtual machines offer. You can read about the specifications for DS Series VM’s in the link posted above. If you were using a standard Azure VM you can easily scale up or down to another standard virtual machine using Portal, PowerShell and Azure CLI. Unfortunately it is currently not possible to upgrade/migrate a standard Azure virtual machine to a DS Series virtual machine with premium storage. In this blog post I will show you how you can migrate an existing virtual machine to a DS’s series virtual machine with Premium(durable SSD) storage. It will provide a PowerShell script you can leverage to migrate a standard virtual machine to a DS Series virtual machine.
Details
Creating Premium Storage Account
Premium storage account is different than standard storage accounts. If you want to leverage premium storage you need to create a new storage account in the azure preview portal. Account type you need to select is “Premium Locally Redundant”
It is not possible to use the existing Azure management portal to provision premium storage account.
Here is how you can use PowerShell cmdlet to create premium storage account. As you can see it is similar to how you create standard storage accounts. I was unable to find what value I had to specify for Type and I had to read the actual source code to determine that it was ‘Premium_LRS’
001
002 003 004 005 006 007 008 |
$StorageAccountTypePremium = ‘Premium_LRS’
$DestStorageAccount = New-AzureStorageAccount -StorageAccountName $DestStorageAccountName -Location $Location -Type $StorageAccountTypePremium -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null if (!($?)) |
Premium storage and DS Series virtual machines are not available in all regions. The complete script I will provide validates your location preference and fails if you specify a location where premium storage and DS Series VM’s are not available.
Creating DS Series Virtual machine is identical to creating standard virtual machines.
Here are a few things I learned about DS Series Virtual machines and Premium storage.
- Premium storage does not allow us to add disks smaller than 10 GB. If your VM has a disk smaller than 10 GB the script will fail
- Default Host Caching option for Premium storage data disks is “Ready Only” as compared with “None” for standard data disks.
- Default Host Caching option for Premium storage OS disk is “Read Write” which is same as standard OS disks
- Currently this script only migrates virtual machines to the same subscription. It can be easily extended to support migration to different subscriptions.
- It can migrate VM’s to a different region as long as premium storage is available in that region
- It shuts down the existing source VM before making of copy of the VHD’s for the virtual machine.
- It validates that virtual network for the destination VM exists but does not validate if subnet also exists
- It gives new names to the disks in the destination virtual machine
- Currently I am only copying disks, end points, VM extensions. I am not copying ACL’s and other type of extensions like malware extension
- I only tested the script with PowerShell SDK Version 0.9.2
- I tested migrating standard VM in West US to DS Series VM in West US only. I logged into the newly created VM and verified that all disks were present. This is the extent of my testing. My VM with 3 Disk’s copied in 10 minutes.
- If your destination storage account already exists it has to be of type “Premium_LRS”. If you have an existing account of different type the script will fail. If the storage account does not exist it will be created.
Sample Script
You can access the entire source code from my public GitHub repository
https://github.com/rajinders/migrate-to-azuredsvm
I have also pasted the entire source code here for your convenience.
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
<#
Copyright 2015 Rajinder Singh Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. #> <# [CmdletBinding(DefaultParameterSetName=“Default”)] [Parameter (Mandatory = $true)] [Parameter (Mandatory = $true)] [Parameter (Mandatory = $true)] [Parameter (Mandatory = $true)] [Parameter (Mandatory = $true)] [Parameter (Mandatory = $true)] [Parameter (Mandatory = $true)] [Parameter (Mandatory = $false)] [Parameter (Mandatory = $false)] #publish version of the the powershell cmdlets we are using #$VerbosePreference = “Continue” ############################################################################################################# #validate upfront that this service we are trying to create already exists #Determine we are migrating the VM to a Virtual network. If it is then verify that VNET exists if (!$vnetSite) Write-Host “DepoyToVNet is set to [$DeployToVnet]” #TODO: add validation to make sure the destination VM size can accomodate the number of disk in the source VM $DestStorageAccount = Get-AzureStorageAccount -StorageAccountName $DestStorageAccountName -ErrorAction SilentlyContinue #check to see if the storage account exists and create a premium storage account if it does not exist $DestStorageAccount = New-AzureStorageAccount -StorageAccountName $DestStorageAccountName -Location $Location -Type $StorageAccountTypePremium -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null if (!($?)) #make sure if the account already exists it is of type premium storage Write-Host “Source VM Name is [$SourceVMName] and Service Name is [$SourceServiceName]” #Get VM Details if($SourceVM -eq $null) Write-Host “vm name is [$($SourceVM.Name)] and vm status is [$($SourceVM.Status)]” #need to shutdown the existing VM before copying its disks. $osdisk = $SourceVM | Get-AzureOSDisk Write-Host “OS Disk name is $($osdisk.DiskName) and disk location is $($osdisk.MediaLink)” $disk_configs = @{} # Used to track disk copy status ################################################################################################################## # Copies to remote storage account #extract the name of the source storage account from the URI of the VHD $vhdName = $sourceDiskUri.Segments[$sourceDiskUri.Segments.Length – 1].Replace(“%20”,” “) $sourceStorageAccountKey = (Get-AzureStorageKey -StorageAccountName $sourceStorageAccountName).Primary $destStorageAccountKey = (Get-AzureStorageKey -StorageAccountName $destStorageAccountName).Primary while((Get-AzureStorageContainer -Name $destContainer -Context $destContext -ErrorAction SilentlyContinue) -eq $null) # Save for later disk registration #start async copy of the VHD. It will overwrite any existing VHD return $copyState ################################################################################################################## function TrackBlobCopyStatus() # Mark the start time of the script execution Write-Host “Destination storage account name is [$DestStorageAccountName]” # Copy disks using the async API from the source URL to the destination storage account # copy all the data disks Write-Host “Disk Name [$($_.DiskName)], Size is [$($_.LogicalDiskSizeInGB)]” #Premium storage does not allow disks smaller than 10 GB #check that status of blob copy. This may take a while if you are doing cross region copies. # Mark the finish time of the script execution Write-Host “Registering Copied Disk” -ForegroundColor Green $luncount = 0 # used to generate unique lun value for data disks $datadisk_details = @{} foreach($diskName in $disk_configs.Keys) $diskConfig = $disk_configs[$diskName].Split(“;”) #since we are using the same subscription we need to update the diskName for it to be unique Write-Host “Adding disk [$newDiskName]” #check to see if this disk already exists if(!$azureDisk) if($diskConfig.Length -gt 1) #Expect OS Disk to be the first disk in the array $vmconfig = New-AzureVMConfig -Name $DestVMName -InstanceSize $VMSize -DiskName $OSDisk.DiskName } Add-AzureDisk -DiskName $newDiskName -MediaLocation $diskConfig[0] $datadisk_details[$luncount] = $newDiskName $luncount = $luncount + 1 #add all the data disks to the VM configuration Write-Host “Adding data disk [$datadisk_name] to the VM configuration” $vmconfig | Add-AzureDataDisk -Import -DiskName $datadisk_name -LUN $lun #read all the end points in the source VM and create them in the destination VM if($_.LBSetName -eq $null) # $vmconfig | Set-AzureSubnet -SubnetNames $SubnetName #get any vm extensions |
Conclusion
I had to look at many different code samples as well as MSDN documentation to create this script. I am grateful to all the open source samples folks are contributing and this is my way of giving back to the Azure community. If you have questions and/or features requests drop me a line and I will do what I can to help.
The post How to migrate from Standard Azure Virtual Machines to DS Series Storage Optimized VM’s appeared first on Raj's Cloud Musings.