VMware Template Management using Hashicorp Packer

VMware Templates: they make life amazing, don’t they? Creating a your first vSphere template is easy, but there are limitations when using them in enterprise environments. In this article, I will talk about the downsides of traditional enterprise template management, how Packer can help, and give examples (and code!) for creating Windows and Linux templates in VMware vCenter using Packer.

Traditional Enterprise Template Management

  1. Templates Across Multiple Sites – create a master template and replicate to ensure the same state exists
    1. Introduces operational complexity
    2. Extends the total amount of time it takes to patch all templates
  2. OS and Application updates need to be performed for every application on every template
    1. Repetition sucks!
    2. Introduces risk due to C2K errors
  3. Template creation ends up being a work of art.
    1. Individuals sometimes spend years fine-tuning all of the customization in a windows template.
    2. On-boarding time is significantly increased
    3. Projects delivered by third parties will take extra time to complete projects, as reverse engineering will need to occur in templates
  4. Documentation? Do you have it for your Windows and Linux Template?

Enterprise Template Management With Packer

  1. You are no longer limited to VMware! The effort used to create the template code can be used to create templates in other hypervisors, and in the cloud
  2. Create net-new templates consistently, eliminating the old method of creating one template, and copying that to data-centers over the world.
  3. Packer defines every configured setting and change for templates in code. Documentation: Check!
  4. Changes to your templates make it into the wild faster and with zero configuration drift.

Source Code

You can find source code for Windows 2019, Windows 2016, and Ubuntu 18 in my GitHub repository: https://github.com/jonhowe/Virtjunkie.com/tree/master/Packer

The remainder of this post will explain how this code works.

Packer Intro

First and foremost, this is not a packer tutorial. Packer actually provides an excellent getting started guide. I’d actually recommend you start there if you have no background with packer. That said, I will blaze through a few concepts.

Packer Template File & User Variables

Packer stores it’s configuration in JSON files and calls them Packer Templates. There are two types of files. Master packer templates, and user variable files. Both are stored in JSON. The easiest way to think of this is the master packer template file contains properties that will be used as a part of the build. The user variable file (that is specified when you actually execute the build.. more on this later) in JSON format provides the values to the properties.


Hashicorp defines builders as:

Builders are responsible for creating machines and generating images from them for various platforms. For example, there are separate builders for EC2, VMware, VirtualBox, etc. Packer comes with many builders by default, and can also be extended to add new builders.

We will be using the builder called VSphere-ISO. This builder communicates directly with the vCenter API, which also makes this relevant for VMC on AWS.

Attaching ISOs and Floppy Images

Packer allows us to attach both ISOs and Floppy images to the VM we are working with.


You can attach multiple ISOs to an image. For example, you can attach a Windows installer ISO, as well as a VMware tools ISO to a Windows VM. Here’s an example of how this works:

Floppy Images

Packer gives us the ability to take a file, a directory, or a floppy image, and present it to the target VM as a floppy image. This is very useful if you want to copy scripts to the VM to be executed locally. Here’s an example of how this works:


Communicators are the mechanism Packer uses to upload files, execute scripts, after the machine is created. Packer uses WinRM and SSH communicators. More on this later.


Provisioners are used to handle post image creation tasks, such as OS Customization and installing updates. Provisioners require communicators. In this case, the WinRM communicator will be used with Windows Images, while the SSH communicator will be used to communicate with Linux. We will be using the following provisioners:

Provisioner Name Used For
Powershell Performing all OS Customization Steps in Windows Images
Windows-Restart Restart Windows Images
Windows-Update Apply Windows updates (community supported)
Shell Used to install updates on Linux machines. We also set a custom “execution_command” that will allow for sudo to be used for all commands.

Linux Templates

Linux templates are pretty straight forward. Being born in open source, they are much easier to automate than Windows. Debian based distributions use a preseed file to silently execute the build. We will use packer to do the following:

  1. Create a blank VM
  2. Attach Linux installer ISO
  3. Create and attach media that has preseed.cfg file to the newly created image
  4. Start VM
  5. Send commands to the running VM via USB emulation to tell the Ubuntu installer to use the preseed.cfg file
  6. Update all packages on the template
  7. Shut Down VM
  8. Mark as Template

Here’s the directory structure:

Windows Templates

Most consumers of Packer are using it to manage Linux images, but I rarely hear about managing Windows images. Windows has a bit more moving parts that cause more complexity. It was way harder for me to figure out, even with a couple of great posts I’ll list in the reference area. In order to have a complete windows template, we will need to achieve the following steps:

  1. Create a blank VM
  2. Attach Windows Installer and VMware Tools ISO
  3. Attach floppy image that contains scripts and autounattend.xml
  4. Start VM
  5. Silently Install Windows Server (windowsPE pass in Autounattend.xml)
  6. Install VMware Tools (Specialize pass in Autounattend.xml executes vmtools.cmd)
  7. Configure WinRM (oobeSystem pass in Autounattend.xml executes level0-setup.ps1)
  8. Perform OS Customization (Packer PowerShell provisioner executes level1-setup.ps1)
  9. Install Windows Updates (Packer Windows Update provisioner applies updates)
  10. Shut Down VM
  11. Mark as Template

Definitely more complex than Linux, eh? Don’t worry though. I’ll do my best to add some value on top of documentation and blog articles that are out there. Here’s the directory structure:


Microsoft allows us to provide an answer file to the Windows installer to achieve a silent install of Windows Server. The installer will look in all attached media to find a file named Autounattend.xml. This file contains a number of settings that are explained in a decent amount of detail on this Microsoft documentation page. Below is a high level overview of the passes and how we are using them.

I found this page helpful in creating the skeleton of the XML file.


  • Select disk format
  • Select the OS Image (Core, GUI, Datacenter, Standard)
  • Add the product key (we’ll be using the 6 month trial)
  • Select Locale, Name, Organization


  • This configuration pass is used to apply updates, drivers, or language packs to a Windows image.



  • This configuration pass is used to create and configure information in the Windows image, and is specific to the hardware that the Windows image is installing to.
  • Install VMware Tools by executing (vmtools.cmd) in this step to ensure it’s available ASAP for Packer to perform the rest of template configuration steps
  • Computer name is set
  • Reboots the machine


  • Add user, set password
  • Execute powershell script (level0-setup.ps1) to enable WinRM, which is required for Packer provisioning


Here are a few examples of how the script works


The command below will create a windows template with the following details.

Username Administrator
Password VMware1!
Additional User Labadmin

If you want to change the password, you will need to specify it both in the vars file, as well as the autounattend.xml. The section you will change looks like this:

In Action


The command below will create a Ubuntu template with the following details:

Root Password VMware1!
Additional Username (also added to sudoers) jhowe
Additional username’s password VMware1!

All of the above can be changed by modifying values in the preseed.cfg file.

In Action


I did a lot of research as when getting this up and running. The following sites were helpful.

2 thoughts on “VMware Template Management using Hashicorp Packer

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright VirtJunkie.com ยฉ 2024