In the
previous part, we looked at what automation of deploying VM Windows is needed for and how to prepare the host system. Today I would like to focus on the technical implementation of the most massive part of the process, namely the preparation of the basic boxing for Vagrant.
After all the necessary software is installed, it's time to prepare an exemplary box - a template from which the machines will unfold. The box is a regular tar-archive containing a VHD disk file and metadata: virtual settings and service information. Thus, it is necessary to start preparing the image with creating a new VM in it, updating it, adjusting and compressing in order to save space and speed up the deployment. I will not dwell on how to create a new virtual machine in Hyper-V Manager, how to install the system and roll updates. I will focus only on the nuances:
- Create the machine of the first generation (Gen1). This is due to the fact that the current version of Vagrant (1.7.2) incorrectly sets the parameters of the hard disk (Gen2 does not have the “IDE” option, it is replaced with “VHD”), so I advise you not to get involved with Gen2 yet. However, if you really need to - you can correct the file plugins / providers / hyperv / scripts / import_vm.ps1.
- Use only one hard disk file, otherwise the box will not be able to climb (see below for details).
- Do not install unnecessary software (including Windows components) in the box. This makes it heavier and increases the chance that after some time there will be an outdated version. It is more correct to do it later, in the stage of provisioning.
- For Boxstarter to work correctly, you need to disable Powershell restrictions:
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
- By default, Vagrant accesses the machine via SSH (which required installing the latter on the machine), but in recent versions he has learned to work using the WinRM protocol native to Windows. All you need is to configure WinRM:
winrm set winrm / config / client / auth '@ {Basic = "true"}'
winrm set winrm / config / service / auth '@ {Basic = "true"}'
winrm set winrm / config / service '@ {AllowUnencrypted = "true"}
- I usually disable (set the manual startup mode) unnecessary services (Print Spooler is the same), and also remove the disk indexing and automatic weekly defragmentation: we have the Storage Tier optimization performed by the hypervisor itself.
After installing all the updates, Windows usually “swells” up to 12-15 gigabytes, which is obviously a bit too much for quick cloning. This is due to the fact that the system caches package installers and distributions of some of its components. All this, fortunately, is easily cleaned. So, how to reduce the volume occupied by the VHD file?
- Reduce the size of the paging file, make this size fixed;
- Clear all logs:
wevtutil el | Foreach-Object {wevtutil cl "$ _"}
- Remove unnecessary components of Windows Update:
Dism.exe / online / Cleanup-Image / StartComponentCleanup / ResetBase
Dism.exe / online / Cleanup-Image / SPSuperseded
- Remove installers component of Windows. By running the Get-WindowsFeature command, you can see that some of the components have Install State = Available. Usually, this means that these components can be installed, and for this purpose enough cache, which is stored directly on the local disk. Therefore, it makes sense to delete this cache by executing the following commands:
Get-WindowsFeature |
? {$ _. InstallState -eq 'Available'} |
Uninstall-WindowsFeature -Remove
- If any of the components may be useful later, it makes sense to leave it, otherwise during subsequent installation you will have to specify the path to the wim file (the -Source parameter). However, there is nothing terrible here: this file is in the ISO file from which the system was installed, and it can be used both locally and from a network resource. In addition, some components are quietly installed from the Internet - Powershell itself downloads the necessary files.
- If desired, you can install Disk Cleanup - a program that automatically cleans the system from temporary files. However, to do this, you need to add the Desktop-Experience role, which, when deleted, causes problems with sysprep. So there are two options: either to leave this feature, which eats up the place and makes the registry heavier (as it pulls up a bunch of mandatory, but too much junk like Ink and Handwriting), or refuse sysprep, which puts an end to the use of the raised machines in the domain.
- After all the listed operations, the size of the dynamic VHD file will remain the same. To compress it, you must first defragment to move all files to the beginning of the disk:
Optimize-Volume -DriveLetter C -Defrag
- After defragmentation, it is advisable to reset all free space using the sdelete command that is part of SysInternals:
sdelete -zc:
This will allow more effectively compress it later.
After that, you can turn off the virtual machine and run Compact operation on its VHD. The total size may vary, but usually it is at the level of 5-7 GB. The final size of the box will be even smaller, because we are going to further compress it with tar and GZip. However, if you plan to use this machine in a domain environment - you need to prepare it so that there is no situation with duplication of SID. To do this, use the Sysprep utility.
Sysprep walking
In the most general case, preparing virtual machines for cloning using sysprep is a rather banal procedure. To do this, you can use as a GUI.
C: \ Windows \ System32 \ Sysprep \ sysprep

as well as the command line, which is closer to our liking and also allows you to specify additional parameters:
C: \ Windows \ System32 \ Sysprep \ sysprep / generalize / oobe / mode: vm / shutdown
After that, the program will perform all the necessary operations and extinguish the car. The next time the system is turned on, it will be in the aforementioned OOBE (Out-of-Box Experience) - the state in which the newly purchased laptop is located when it is first turned on: hardware inventory will be taken, local administrator password, license key, computer name and so on will be requested. All anything, but you have to enter all this manually, from the keyboard. Fortunately, all this is easily automated. To do this, you need to prepare an answer file, unattend.xml and put it next to the sysprep.exe file launched (in the C: \ Windows \ System32 \ Sysprep folder), or by specifying the path to it as a command line parameter - this will allow you to place the file on the external disk so that it does not appear on the final box. I will not dwell on this in detail; I just want to say that this will require a Windows installation image (more precisely, an install.wim file from it) and a Windows Assessment and Deployment Kit (ADK) (you need only install the Deployment Tools item, which includes the Windows System Image Manager). Links to the distribution, instructions and examples of use will be in the appropriate section in the next, final part of the article.
Important nuances:
- If you installed and then deleted the Desktop-Experience component, then Sysprep will fall out with an error. As I mentioned above, there are two options: either to leave this component installed, or to do without it. Matt Rock (author of Boxstarter) has the details on his blog .
- When preparing boxing, it is often necessary to modify something; for this, boxing rises in the OOBE state, all settings are passed according to the response file, then necessary changes are made and the system is run again by Sysprep. I want to note that this will happen only twice (i.e., three sysprep runs). This is due to the peculiarities of licensing Microsoft. In principle, this costs tricky editing of the registry , but this can be done only for temporary or test machines, and not in production, so I advise you to simply store the image for further work separately, making copies of it if necessary and preparing the new version independently. Thus, each virtual machine for the entire period of its life will be “otprepreplena” just once.
- It is better not to set the name of the computer - then it will be randomly generated, which will avoid confusion and conflicts when several machines rise at the same time. In addition, it can be easily installed by the employee at the stage of provisioning during the ascent.
- Set a complex and secure password for the local administrator. In the future, of course, it is better to change it (or block it altogether). This account will be required when raising the machine at the provisioning stage: it is under it that Vagrant will install the software, update the system and make all the necessary settings.
- The name of the machine in the hypervisor itself (as it is called in the Hyper-V Manager) is better to change to something short and simple - that is the name of the machine from the expanded box. There was an awkward situation when my colleagues raised my trial box and as a result they had a machine like “Winda 2k12 r2 x64 syspreped with bloody winrm settings version 111 test 222 yo”.
Boxing packaging
After Sysprep put out the car, it's time to pack the virtual machine in a boxing file. In general, Vagrant has built-in functionality for this (command provision), however, as of now, it does not work in Hyper-V. So we’ll pack up the box with our hands - there’s nothing to be afraid of, it’s done quite simply:
- The machine checks the hardware configuration: the number of processor cores, memory size, boot priority. It is these parameters that will be on newly deployed machines (although nothing prevents to change them later, of course).
- All snapshots of the hard disk are deleted.
- The finished off machine is exported to a separate folder on the disk. This is necessary to place the file of the hard drive and all the meta-information alongside.
- In the folder with the virtual machine, the folder for snapshots files is deleted - the Wagrant provider Hyper-V still does not use it.
- A text file metadata.json is also created there. At a minimum, at least one provider must be defined there (Hyper-V in our case). Example file for our case:
{
"Name": "Windows2012R2",
"Description": "Windows 2012 R2 box sysprepped with ununtended provisioning",
"Provider": "hyperv"
}
- Now it only remains to make a .box file from the directory contents. To do this, use tar (you can use the free 7-Zip or bsdtar from the repository: the version that comes with Vagrant 1.7.2 will not work). Attention: the archive should contain only the contents of the folder to which the machine was exported, without the parent folder, otherwise the box is not recognized. Those. inside, right in the root should be the “Virtual Hard drives” and “Virtual Machines” directories, as well as the metadata.json file. The resulting file can then be compressed using gzip (7-Zip can be used again, the main thing is to do it in a separate iteration, already above the .tar file) or LZMA (which gives better compression, but the time saved on copying will be spent for a longer time compared to gzip, unzip) and change its extension to box. TA-dah! Boxing is ready!
Now, in order for Vagrant to copy it to itself and see — you need to add it using the add command directly from our directory with the file:
vagrant box add --provider hyperv --name Win2012R2x64 Win2012R2.box
If everything went well, the box will become available (the vagranate will copy it to himself in% VAGRANT_HOME% and unpack it) and you can see it in the output of the vagrant box list command. To make it available for colleagues - you can put it on a shared network drive (then the command for adding a box will be vagrant box add --name Win2012R2x64 D: \ Path \ To \ Win2012R2x64 \\ fileserver.domain.local \ boxes \ win2012r2. box) or web server: local (vagrant box add - name Win2012R2x64 http: //devops.local/boxes/win2012r2.box) or external. For example, at
http://www.vagrantbox.es/ or
Hashicorp Atlas .
In the
next part, I will show you how to lift a VM from boxing and perform its automatic tuning with the help of provisioning.