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.


user, env

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

"app_name": "{{app_name_cmd_var}}"
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}}


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.


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


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.

Packer: WinRM

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

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.

GitHub: ruzickap/packer-templates