Building Machine Images with Packer
It may seem like an obvious statement, but one of the primary concerns for the Windows team is to deploy Windows servers and workstations. Over the last two years, we have more than tripled the number of Windows machines deployed within our estate meaning that the team had to consider how best to deal with this expansion and how to keep up with demand.
Installing windows and running through a list of to-dos isn’t going to scale very well and whilst we do use a lot of automation to deploy Windows, such as Ansible and DSC, it can take a long time to get a fresh windows installation updated and fully configured (assuming nothing goes wrong during the process).
The answer lies in creating machine images. In the past this was done by hand to produce the “Golden Image” that every windows deployment would use. But now keeping multiple golden images up to date and clean becomes a burden, not to mention extremely boring. Instead we turned to Packer.
What is it?
Packer is an open source tool from HashiCorp for creating identical machine images for multiple platforms from a single source configuration. It allows us to codify our Windows images and build them from scratch in an automated, reliable and repeatable way. This solves a few problems for us:
- Time: building an image is a slow process but it’s completely hands-off and runs through continuous integration meaning we can spend more time on other improvement work
- Scalability: Because the image is described with a single text file we can make many more types of images. Disk space becomes the only limiting factor
- Source Control: Now we can say with a high degree of confidence exactly what is in our images and version control them, whereas before this wasn’t possible
- Customisation: We can now create much more customised images with minimal effort to better support the intended purpose of each server
- Platforms: We can now build identical images for any platform. Currently we build VMWare Templates for VMs and WIMs for physical servers but we can easily extend this to AWS, Docker, OpenStack etc.
Below is a snippet of a Packer configuration file.
Using the right tools
Packer has some helpful features for letting you define multiple images with differing configurations but they only extend so far. The file depicted above actually continues to line 300. To codify the level of customisation we wanted, whilst maintaining readable code with minimal repetition, we decided to introduce a new tool, Jinja2.
Jinja2 is a templating language written in python. Using this allowed us to split out each configuration item into its own file and use Jinja2 to recombine them where needed for each different types of image we wanted to create. The result was a more readable and reusable codebase.
Our current packer configuration files now look like this:
Another tool we use in conjunction with packer is Bamboo. For those who are not familiar, Bamboo is a continuous integration engine. Its primary roles is to pick up on changes to our packer codebase, automatically invoke the Jinja2 templating and start a packer build. To illustrate the process, this all happens without any human intervention:
Our adoption of Packer is by no means complete. Whist we have greatly reduced the time and effort required to deploy windows, we still rely on lengthy processes to further configure and install software on top of these images. A lot of this process is also error prone due to the complexity of the estate and variance in configuration between servers.
In an ideal world we would deploy machine images that require little to no configuration to get them ready for production. These machines would be treated as immutable and simply replaced with newer images instead of laboriously patching them over the course of many years.
In reality this isn’t going to be possible in our current environment, at least not for the time being. That is not to say this isn’t the direction we should all be going! Docker containers is an example of another technology that will help us get to something more akin to the ideal. The next steps for us to move one step closer to this are:
- Encapsulate more into our images to reduce the amount of post-deployment configuration required, such as more preinstalled software
- Create more machine images to accommodate for different server roles. Currently we build three varieties of Windows 10 and 2 varieties of Server 2016.
- Start using VMWare templates for any new VMs which will cut down the time to provision substantially
- Provide self-service VMs
When it comes to building Windows machines on AWS and on our on-prem Cloud environment based on OpenStack, we need to be ready to meet demand and put into practise more rigorously these concepts.
By Scott Matthews – Technology