-
Notifications
You must be signed in to change notification settings - Fork 36
Capturing An Image
If you want to capture an image that you can use for future provisioning, then you will need to capture it. This requires a series of steps.
For our example, we'll assume that you've provisioned a Windows VM and that it's currently running.
We'll need to run sysprep on the VM before we begin. Because this is a Windows VM, we'll need to use the winrm gem to run a command remotely.
You could, of course, use Microsoft Remote Desktop instead and do this manually if you prefer. In fact, winrm may not be enabled by default, depending on the type of VM that you've provisioned.
gem install winrm
With that installed, connect and run sysprep. This will automatically shutdown the VM upon completion, and may take a few minutes.
require 'winrm'
options = {
:endpoint => 'http://1.2.3.4:5985/wsman' # Put actual IP here
:user => 'foo\Administrator' # Or whomever
:password => 'xxx' # Put real password here
:operation_timeout => 1800
}
# Your exact options may vary
connection = WinRM::Connection.new(options)
script = '$Env:SystemRoot\system32\sysprep\sysprep.exe /generalize /oobe /shutdown'
connection.create_executor do |exec|
output = shell.run(script)
if output.stderr && output.stderr.size > 0
puts "OOPS: #{output.stderr}"
else
puts "RESULT: #{output.stdout.strip}"
end
end
For a Linux VM, ssh into the VM using net-ssh or the command line, and run the following:
sudo waagent -deprovision+user -force
You'll need to setup your credentials with a tenant ID, client ID, and client key. If you have more than one subscription associated with your tenant, I recommend specifying the subscription ID as well.
require 'azure-armrest'
conf = Azure::Armrest::ArmrestService.configure(
:client_id => 'xxx',
:client_key => 'yyy',
:tenant_id => 'zzz',
:subscription_id => 'xxx'
)
First we'll need to deallocate the virtual machine
vms = Azure::Armrest::VirtualMachineService.new(conf)
your_vm = 'your-winimg'
res_group = 'your_resource_group'
vms.deallocate(windows_vm, res_group)
Using the CLI you would do this:
az vm deallocate -n your_vm -g your_group
Once the VM is deallocated, we need to first generalize it, i.e. make it suitable as an image that other VM's can then be provisioned from:
vms.generalize(windows_vm, res_group)
If the VM you created is unmanaged (i.e. using unmanaged storage), then create an image using the capture
method like so:
# Note that you can write these options like 'vhdPrefix' or 'vhd_prefix', as you choose
options = {
:vhdPrefix => "test-win2k12-img", # Or whatever
:destinationContainerName => "your-test-container",
:overwriteVhds => true
}
vms.capture(your_vm, options, res_group)
If the VM you created is managed (most likely), then you will need to create an image using a different service:
ims = Azure::Armrest::Storage::ImageService.new(conf)
vm = vms.get(your_vm, res_group)
options = {
:location => 'West US',
:properties => {
:source_virtual_machine => {:id => vm.id}
}
}
ims.create(name, group, options)
Using the CLI for a managed VM:
az image create -n your-vm-img -g your-group --source your-vm
For unmanaged images, your captured image now resides in the storage account as a blob. You can view it in the portal under Blob service -> system -> Microsoft.Compute -> Images -> your-test-container.
You can also see it using the armrest gem like so:
sas = Azure::Armrest::StorageAccountService.new(conf)
storage_acct_name = 'your_storage_acct'
p sas.list_private_images(res_group)
For managed images, you can see a list of images using the Azure::Armrest::Storage::ImageService
instance we created earlier:
p ims.list_all
This documentation basically follows this blog post: http://www.codeisahighway.com/how-to-capture-your-own-custom-virtual-machine-image-under-azure-resource-manager-api/
See also: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/tutorial-custom-images