Packer is a really awesome modern tool for automating the process of provisioning images. This in conjunction with source control (preferably Git) and Vagrant can mean that your portable Hyper-V, VirtualBox or VMWare images are maintainable and immutable. Through provisioners, Packer can build in many different environments including cloud infrastructure. There’s a lot of good documentation out there and I’m going to put my notes here. Packer can also use ISO images to build virtual machines for VirtualBox, VMWare, and Hyper-V.
Building an Image with Packer
Before we get into this, I want to give a high-level overview of what this does to set some expectations. I’m building a Windows Server 2019 image and the first command I run is to build the image from a JSON file.
This immediately starts building a Hyper-V image without me doing anything because Packer programmatically builds Virtual Machines. This is known as provisioning.
Packer can build images for Amazon EC2, DigitalOcean, Google Cloud Platform, LXC, Linode, Microsoft Azure, QEMU, VMWare, Hyper-V, Docker, Vagrant, and VirtualBox. It’s even possible to create your own builders.
This command takes a packer template file and runs all the builds within it to create images. Good to know flags are
Running packer validate will allow you to validate syntax and configuration of a packer template file.
Packer fix is essential to bringing older packer templates up to more modern releases of packer.
To get the version of packer run
Using a Variable File
By using the command `-var-file=variables.json` you can easily reference variables in another file.
packer build -var-file=variables.json template.json
Command-Line with Custom Variables
packer build -var 'app_name_cmd_var=apache' apache.json
Using Variables in Packer
Variables are very easy to use in Packer. Creating a section in the JSON file called “variables” provides a key-value reference that can be used in multiple builders. A variable can be referenced using
A packer builder is part of the packer template that defines a section of JSON that packer will use to build within specific environments like Amazon EC2, Azure, DigitalOcean, Docker, or a Virtual Machine.
Communicators are what Packer uses to interact with the machine being created. Typically, the default communicator is the SSH protocol and that’s what Packer uses to upload files, execute scripts, and run any other commands against the box. For Windows machines, WinRM is an option as a communicator.
Packer can use ISO files to build images. There are properties that go to the Packer template file that will use checksum and file paths to verify and reference the ISO file.
If using answer files isn’t an option it’s also possible to use boot commands. For example there are commands for keys strokes, waiting for the purpose of Packer interacting with the installation as if it were a human entering those keys.
You ran read more about boot commands for a VirtualBox image here.
Common Boot Commands for VirtualBox
- <bs> – Backspace
- <del> – Delete
- <enter><return> – As if the user pressed the enter key.
- <esc> – Escape
- <tab> – Tab
- <f1> – <f12> – Any of the keys between F1 and F12.
- <wait>, <wait5>, <wait10> – This will cause the installation to wait for however many seconds.
The image below is from a Packer template that is configuring a VirtualBox image of Kali.
Getting started with packer is much easier if you find a good template to customize. Some templates will already have the answer files mostly configured and they are easy to tweak.
Packer Windows Images
When building Windows images it’s important to mount the answer file, autounattend.xml in the floppy_files configuration because that’s where it will look by default. It’s also possible to mount the answers file using the boot_command.
Packer can also use the WinRM communicator to configure Windows images.
Downloading trial and evaluation ISOs from Microsoft is a great way to play around with Packer. They are typically usable for up to 180 days.
Packer Linux Images
Packer with Vagrant
if you’re going to use Packer to build Vagrant images there are a couple of things you need to remember.