3
votes

NOTE: This is an Azure ARM question - not an Azure Service Management question.

I have 2 vhds in a storage account - machine-os.vhd and machine-data.vhd. I can use PowerShell ARM cmdlets to create a VM with the existing OS vhd, but cannot figure out how to attach the EXISTING data vhd. All the samples I have found create EMPTY data disks - but I want to attach the existing vhd as a data disk.

I've tried to use the createOption attach switch with Add-AzureVMDataDisk like so:

$vm = New-AzureVMConfig ... $vm = Add-AzureVMDataDisk -VM $vm -VhdUri $existingDiskUri -Name "machine-data.vhd" -Caching ReadOnly -CreateOption attach -DiskSizeInGB 200

However, the operation fails with:

Blob https://x.blob.core.windows.net/vhds/machine-data.vhd already exists. Please provide a different blob URI to create a new blank data disk 'machine-data.vhd.'

I have to specify DiskSizeInGB for the Add-AzureVMDataDisk command to work (which seems strange). I've tried specifying SourceImageUri and a different name for the VhdUri, which, according to the documentation, should copy the vhd from the sourceImageUri to the vhdUri and attach it. Trying createOption fromImage fails because "you cannot specify size with source image uri". However, the size parameter for the cmdlet is mandatory, so I don't know how you could specify an sourceUri and not a size.

This SO question presents a similar issue (though I don't get the same error), but the link in the answer shows a template with EMPTY data disks, which doesn't help.

Interestingly I've tried to add the disk to the VM from the Azure Portal - there you have to specify a name and a URI, but the operation always fails with some strange json parsing error. I can't seem to get the uri for the data disk correct.

1

1 Answers

0
votes

After playing around a bit more I found a hack:

  1. Give a new URI for the existing disk and set this as the vhdUri
  2. Use the URI of the existing disk as the sourceImageUri
  3. Call Add-AzureVMDataDisk using the CreateOption fromImage
  4. Set the size of the data disk to null (this is the hack)
  5. When calling New-AzureVM, the existing disk is copied to the new Uri
  6. After creating the VM, I delete the original vhd

Unfortunately you have to supply the DiskSizeInGB parameter to the Add-AzureVMDataDisk command since it's mandatory. However, I set it to null, otherwise the provisioning fails (the error message says that you can't specify both size and sourceImageUri).

Here's the final code:

$vm = New-AzureVMConfig ...
$vm = Add-AzureVMDataDisk -VM $vm `
      -SourceImageUri $existingDataDiskUrl -VhdUri $newDataDiskUri `
      -Name $newDataDiskName -CreateOption fromImage -Caching ReadOnly `
      -DiskSizeInGB 200

# hack
$vm.StorageProfile.DataDisks[0].DiskSizeGB = $null

After that you can call: New-AzureVM -ResourceGroupName $rgName -Location $location -VM $vm

Once the VM is created, I call Remove-AzureStorageBlob to delete the original disk.

Perhaps there's a cleaner way, but I can't find one. At least this way works in the end.