Creating Azure VM from custom image

9.8k views Asked by At

I have an image stored in Azure that I want to spin up multiple VMs from. I've created a template that will create the necessary resources for me and all of them succeed except the VM creation.

Using CreateOption.FromImage runs the deployment for around 40 minutes until I get the error:

'OS Provisioning for VM 'vmName' did not finish in the allotted time. However, the VM guest agent was detected running. This suggests the guest OS has not been properly prepared to be used as a VM image (with CreateOption=FromImage). To resolve this issue, either use the VHD as is with CreateOption=Attach or prepare it properly for use as an image

Changing CreateOption.FromImage to CreateOption.Attach gives me the following error immediately:

Cannot attach an existing OS disk if the VM is created from a platform or user image.

What I'm trying to achieve through the template:

  1. Point to master image
  2. Supply desired destination for a copy of the master
  3. Copy the master image to the destination
  4. Create the VM
  5. Attach the copy to the VM

Below is the VM portion of the template I'm using to deploy:

{
  "apiVersion": "2015-06-15",
  "type": "Microsoft.Compute/virtualMachines",
  "name": "[parameters('vmName')]",
  "location": "[resourceGroup().location]",
  "tags": {
    "displayName": "VirtualMachine"
  },
  "dependsOn": [
    "[concat('Microsoft.Network/networkInterfaces/', parameters('nicName'))]"
  ],
  "properties": {
    "osProfile": {
      "computerName": "[parameters('vmName')]",
      "adminUsername": "[parameters('adminUsername')]",
      "adminPassword": "[parameters('adminPassword')]"
    },
    "hardwareProfile": {
      "vmSize": "[variables('vmSize')]"
    },
    "storageProfile": {
      "osDisk": {
        "name": "[parameters('OSDiskName')]",
        "osType": "windows",
        "caching": "ReadWrite",
        "createOption": "FromImage",
        "image": {
          "uri": "[concat('https://', parameters('storageAccountName'), '.blob.core.windows.net/', parameters('sourceStorageContainerName'), '/', parameters('sourceVHDName'), '.vhd')]"
        },
        "vhd": {
          "uri": "[concat('https://', parameters('storageAccountName'), '.blob.core.windows.net/', parameters('vhdStorageContainerName'), '/', parameters('OSDiskName'), '.vhd')]"
        }
      }
    },
    "networkProfile": {
      "networkInterfaces": [
        {
          "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]"
        }
      ]
    }
  }
}
2

There are 2 answers

2
Fei Han On BEST ANSWER

'OS Provisioning for VM 'vmName' did not finish in the allotted time. However, the VM guest agent was detected running. This suggests the guest OS has not been properly prepared to be used as a VM image (with CreateOption=FromImage). To resolve this issue, either use the VHD as is with CreateOption=Attach or prepare it properly for use as an image

If you are using the image that is not sysprepped to create VM, it could cause the error, so please make sure your image is sysprepped.

enter image description here

Cannot attach an existing OS disk if the VM is created from a platform or user image.

When you specify CreateOption to Attach ( it will create a virtual machine from a specialized disk), do not specify the SourceImageUri parameter. For more information, please check “-CreateOption” from this documentation.

0
J.Wincewicz On

As Fei Han said, your machine looks like it is not Generalized (generalization of the VM prepares it by creating a generic image what means it removes instance-specific data (paths, registry keys, etc).

To generalize machine you can run this script on it (WARNING! This will make you unable to use this VM anymore):

if( Test-Path $Env:SystemRoot\\System32\\Sysprep\\unattend.xml ){ 
    rm $Env:SystemRoot\\System32\\Sysprep\\unattend.xml -Force
}

& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit

while($true) { 
    $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; 

    if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { 
        Write-Output $imageState.ImageState; Start-Sleep -s 10  
    } else {
        break
    }
}

However, I tried to create an Azure Image from such VM (already deserialized) in Azure Portal I had the same error. That is why, I explicitly passed it to the command to treat my VM as generalized:

$rgName = "rg-my-images"
$location = "Your Region"
$imageName = "vmimg-name-of-your-image"
$osVhdUri = "https://xxxxx.blob.core.windows.net/system/Microsoft.Compute/Images/images/packer-osDisk.[ID of your image].vhd"


$imageConfig = New-AzImageConfig -Location $location
$imageConfig = Set-AzImageOsDisk -Image $imageConfig -OsType Windows -OsState Generalized -BlobUri $osVhdUri
$image = New-AzImage -ImageName $imageName -ResourceGroupName $rgName -Image $imageConfig