HashiCorp Packer
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 Anatomy
Packer is composed of builders, a template file, answer files, boot commands, and integrates with configuration management like Chef, Ansible, or Puppet.
Packer Integrations
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.
Packer Commands
packer build
This command takes a packer template file and runs all the builds within it to create images. Good to know flags are -var
, -var-file
, and -debug
.
packer validate
Running packer validate will allow you to validate syntax and configuration of a packer template file.
packer fix
Packer fix is essential to bringing older packer templates up to more modern releases of packer.
packer version
To get the version of packer run packer --version
.
Variables
user, env
Using a Variable File
By using the command -var-file=variables.json
you can easily reference variables in another file.
1 |
packer build -var-file=variables.json template.json |
Command-Line with Custom Variables
1 |
"app_name": "{{app_name_cmd_var}}" |
1 |
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 {{user vm_name}}

Builders
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.
Provisioners
There are many ways to provision the image after it has been created. Packer works well with many provisioners like Ansible, Chef, Salt, Shell Scripts, PowerShell, Windows CMD, and copying files.
Cloud Providers
Again, Packer integrates with major cloud providers like Amazon AWS, DigitalOcean, and Microsoft Azure.
Communicators
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.
ISO Files
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.

Boot Commands
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.

https://github.com/elreydetoda/packer-kali_linux/blob/master/templates/template.json
Packer Templates
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.
GitHub: StefanScherer/Packer-Windows
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.
https://www.microsoft.com/en-US/evalcenter/evaluate-windows-server-2019?filetype=ISO
https://www.microsoft.com/en-us/evalcenter/evaluate-windows-10-enterprise
Packer Linux Images
GitHub: mrlesmithjr/packer-templates
Packer with Vagrant
if you’re going to use Packer to build Vagrant images there are a couple of things you need to remember.