Upgrade Packer JSON Template to HCL2
As of version 1.7.0, HCL2 is the preferred way to write Packer templates. You can use the hcl2_upgrade
command to transition your existing Packer JSON template to HCL2. This enables you to preserve your existing workflows while leveraging HCL2’s advanced features like variable interpolation and configuration composability.
In this tutorial, you will upgrade a Packer JSON template that builds a Docker image to HCL2. Then, you will add provisioners and post processors to the upgraded HCL2 template.
Prerequisites
This tutorial assumes that you are familiar with the standard Packer workflow. If you are new to Packer, complete the Get Started tutorials first. These tutorials will also introduce you to HCL2 blocks.
For this tutorial, you will need:
- the Packer CLI 1.7+ installed locally
- Docker
Clone the sample repository
Clone the sample repository for this tutorial, which contains a Packer template to create a Docker image.
Change into the repository directory.
Review Packer template
Open docker-ubuntu.json
.
This is a standard Packer JSON template that has a variable, a builder and a provisioner. This template runs an ubuntu:xenial
Docker container, prints the "Hello world!" string, then saves the container to a Docker image.
Upgrade Packer JSON template to HCL2
Use the hcl2_upgrade
command to upgrade the JSON template to HCL2. The -with-annotations
flag provides context for the auto-generated template.
Review the HCL2 configuration
Open the newly created Packer template, docker-ubuntu.json.pkr.hcl
.
The generated HCL2 template file contains three blocks:
- A variable block that defines the image variable,
- A source block that defines the builder Packer will use to build the image, and
- A build block, a composite block, that defines what Packer will execute when running
packer build docker-ubuntu.json.pkr.hcl
.
The build block is similar to the full JSON build template file, with the "variables" and "source" block defining values and builders Packer will use for your images. You can reference "variables" and "source" blocks across multiple HCL2 template files or builds — see build-level source blocks for an example on source block reuse.
Update generated template
The hcl2_upgrade
command automatically maps and generates the relevant HCL2 block.
You should rename these blocks to accurately represent and describe the resource. Rename docker.autogenerated_1
to docker.ubuntu
.
In addition, since this Packer template uses the Docker v0.0.7
plugin, add the following packer
block to the top of docker-ubuntu.json.pkr.hcl
. This ensures Packer will retrieve the Docker plugin that fulfills the version contraint, so you can consistently generate an image from this template.
Build Packer image
First, initialize your template.
Then, build your image. The packer build .
command loads all the contents in the current directory. You can also build specific images by specifying the template file directly.
List the images to verify Packer successfully built the image. The image ID should match the SHA
produced in the Packer output.
Modify template
Now that you have built an image using a HCL2 template, you will now add a provisioner and post-processor to your template.
First, add the following provisioner in the build block after the existing provisioner.
This block defines a shell provisioner which sets an environment variable named FOO
in the shell execution environment and runs the commands in the inline
attribute. This provisioner will create a file named example.txt
that contains FOO is hello world
.
Next, add the following post-processor in the build block after the provisioner blocks.
This post-processor block will tag the newly created image with ubuntu-xenial
.
After adding these provisioner and post-processor blocks, your build block should look like the following.
Build modified Packer image
Build your image.
In the output, you will find Adding file to Docker Container
that confirms that the Packer ran the second provision block.
Verify Docker image
List the images to verify Packer successfully tagged the image.
To verify the provisioner created the example.txt
file in the new image, first launch the newly created Docker image. Replace IMAGE_ID
with the value shown above in your terminal (your local equivalent of 513c63d6a34a
as shown in the output above).
In the Docker container shell, print the contents of the example.txt
file. This should return FOO is hello world
as expected.
Type exit
to leave the container.
Next steps
In this tutorial, you upgraded a Packer JSON template to HCL2. Then, you added provisioners and post processors to the upgraded HCL2 template.
Refer to the following resources for additional details on the concepts covered in this tutorial:
- Read more about the
hcl2_upgrade
command and Packer HCL2 syntax. - Read more about the
init
command. - Learn how to provision infrastructure with Packer and Terraform.
- Read more about why Packer switched from JSON to HCL2 in HashiCorp Packer with HCL Configs blog post.