As of version 1.7.0, HCL2 is the preferred way to write Packer models. You can use the...hcl2_update
to convert your existing Packer JSON template to HCL2. This allows you to maintain your existing workflows while taking advantage of HCL2's advanced features such as variable interpolation and configuration compositing.
In this tutorial, you'll update a Packer JSON template that creates a Docker image for HCL2. It then adds provisioners and post processors to the updated HCL2 model.
This tutorial assumes that you are familiar with the standard Packer workflow. If you are new to Packer, fill out thisGetting Started TutorialsFirst. These tutorials will also introduce HCL2 blocks.
For this tutorial you will need:
- oPackager-CLI1.7+ installed locally
- stevedore
Clone the sample repository
clone thosesample repositoryfor this tutorial which includes a packager template to create a docker image.
ps gitClone https://github.com/hashicorp/learn-packer-upgrade-json-config.git
Change to the repository directory.
ps CDlearn-packer-update-json-config
Opendocker-ubuntu.json
.
{ "Variables":{ "Image":"ubuntu:xenial" }, "builders":[ { "Type":"Dutchman", "Image":"{{user `image`}}", "commit":TRUE } ], "Delivery":[ { "Type":"Concha", "online":[ "I miss hello world!" ] } ]}
This is a standard JSON Packer template with a variable, a constructor, and an implementation service. This model makes aubuntu:xenial
Docker container, prints the message "Hello world!" string and then stores the container in a Docker image.
Update the Packer JSON template for HCL2
use thehcl2_update
Command to update the JSON template for HCL2. EITHER-with-annotations
flag provides context for the automatically generated model.
ps Packer hcl2_upgrade -with-annotations docker-ubuntu.jsondocker-ubuntu.json.pkr.hcl built successfully
Check HCL2 configuration
Open the newly created packager template,docker-ubuntu.json.pkr.hcl
.
# This file was automatically generated by the 'packer hcl2_upgrade' command. Us# We recommend verifying that everything is correct before continuing. Us# I also recommend treating this file as a disposable file. HCL2 blocks it# The file can be moved to other files. For example, variable blocks can be# moved to its own 'variables.pkr.hcl' file, etc. These files must be# suffixed with ".pkr.hcl" to make it visible to packers. How to use multiple files in# as they must also be in the same folder. 'packager watch folder/'# will describe to you what is in this folder.# Avoid mixing template Go calls (for example, ```{{ upper(`string`) }}``` )# and HCL2 calls (for example, '${ var.string_value_example }' ). they will not be# executed together and the result is unknown.# All generated input variables are of type 'string' because that's how Packer JSON works# Look at these; You can change the type later. Read the type of the variable# Constraints-Documentation# https://www.packer.io/docs/templates/hcl_templates/variables#type-constraints for more information.Variable"Image"{ type =rope Standard = "ubuntu:xenial"}# source blocks are generated from their constructors; a source can be referenced# building blocks. A basic component runs the provisioner and post processors in one# Fountain. Read the source block documentation here:# https://www.packer.io/docs/templates/hcl_templates/blocks/sourceThose"Dutchman" "auto generated_1" { commit = TRUE image = "ps{Eras.image}"}# A building block invokes sources and performs implementation steps on them. EITHER# The documentation for the building blocks can be found here:# https://www.packer.io/docs/templates/hcl_templates/blocks/buildbuild { Fuentes = ["source.docker.autogenerated_1"] commissions"Concha"{ online = ["I miss hello world!"] }}
The generated HCL2 model file contains three blocks:
- A variable block that defines the image variable.
- A source block that defines the constructor that Packer uses to create the image and
- A building block, a composite block that defines what Packer will do when it runs
docker-ubuntu.json.pkr.hcl Packager-Build
.
The building block is similar to the full blueprint JSON file, with the Variables and Source blocks defining the values and constructors that Packer uses for its images. You can reference "variables" and "source" blocks in different builds or HCL2 template files; seeBuild Level Source Blocksan example of source block reuse.
ohcl2_update
The command automatically maps and generates the relevant HCL2 block.
You must rename these blocks to accurately represent and describe the feature. renamedocker.autogenerated_1
fordocker.ubuntu
.
-Quelle „Docker“ „autogenerated_1“ {+source "docker" "free" { confirm = true image = "${var.image}" } build {-sources = ["source.docker.autogenerated_1"]+sources = ["source.docker.ubuntu"] ## … }
Also, since this packager template uses Dockerv0.0.7
Plugin, add the followingPacker
obstructdocker-ubuntu.json.pkr.hcl
. This ensures that Packer gets the Docker plugin that meets the version constraint, so it can consistently build an image from this template.
Packer { required_plugins { stevedore = { execution = ">= 0.0.7" Those = "github.com/hashicorp/docker" } }}
Create packager image
First initialize your model.
ps Wrapper initialization.
Then build your image. EITHERPackerbau.
The command loads all the content in the current directory. You can also create specific images by specifying the template file directly.
ps build packers.Docker.ubuntu: The output is in this color.==> docker.ubuntu: creating a temporary directory to share data...==> docker.ubuntu: Extracted Docker-Image: ubuntu:xenialdocker.ubuntu:xenial: Extract from library/ubuntudocker.ubuntu: Zusammenfassung: sha256:eed7e1076bbc1f342c4474c718e5438af4784f59a4e88ad687dbb98483b59ee4docker.ubuntu: Status: Image is up to date for ubuntu: xenialdocker.ubuntu: docker.io/library/ubuntu:xenial==> docker.ubuntu: starting the docker container...docker.ubuntu: run the command: docker run -v /Users/youruser/.packer.d/tmp435754690:/packer-files -d -i -t --entrypoint=/bin/sh -- ubuntu:xenialdocker.ubuntu: enthält ID: bc3bcc9ed53bc2291fe2c31a93521ccd3ff45da38e2781ff9a57fe313f297dfc==> docker.ubuntu: use Docker Communicator to connect: 172.17.0.3==> docker.ubuntu: Provisionando-com-Shell-Skript: /var/folders/s6/m22_k3p11z104k2vx1jkqr2c0000gp/T/packer-shell800525815docker.ubuntu: Hello world!==> docker.ubuntu: Commit-ContainerDocker.ubuntu: ID de imagen: sha256:e763bc0ceb4873075a28b80986aa344d489861f4237a2049bd95025c1ec21882==> docker.ubuntu: Matando o de Inhalt: bc3bcc9ed53bc2291fe2c31a93521ccd3ff45da38e2781ff9a57fe313f297dfcCompilation of 'docker.ubuntu' completed in 4 seconds and 487 milliseconds.==> Timeout ended after 4 seconds 487 milliseconds==> Constructions completed. Artifacts from successful builds are:--> docker.ubuntu: Imagen importada de Docker: sha256:e763bc0ceb4873075a28b80986aa344d489861f4237a2049bd95025c1ec21882
List the images to verify that Packer successfully created the image. The image ID must match theSCHA
produced at the exit of the packing house.
ps dockable imagesID OF THE REPOSITORY TAG CREATED IMAGE SIZE<none> <none> e763bc0ceb48 3 minutes ago 134 MB##...
Now that you've created an image using an HCL2 template, add a provisioner and post processor to your template.
First add the next provider in the building block after the existing provider.
commissions"Concha"{ Environment Variables = [ "FOO = hello world", ] online = [ "add echo file to docker container", "echo \"FOO ist $FOO\" > example.txt", ]}
This block defines a shell provider that sets an environment variable namedFOO
in the shell runtime environment and execute the commands in theonline
Attribute. This provider creates a file calledexample.txt
This containsFOO is hello world
.
Then add the following post processor in the builder block after the setup blocks.
postprocesador"dockable tag" { Repository = "learn to pack" Sign = ["ubuntu-xenial"]}
This post processor block marks the newly created image withubuntu-xenial
.
After adding these provisioning and post processor blocks, your building block should look like this.
build { Fuentes = ["fuente.docker.ubuntu"] commissions"Concha"{ online = ["I miss hello world!"] } commissions"Concha"{ Environment Variables = [ "FOO = hello world", ] online = [ "add echo file to docker container", "echo \"FOO ist $FOO\" > example.txt", ] }postprocesador"dockable tag" { Repository = "learn to pack" Sign = ["ubuntu-xenial"] }}
Create Modified Packager Image
Build your image.
ps build packers.Docker.ubuntu: The output is in this color.==> docker.ubuntu: creating a temporary directory to share data...==> docker.ubuntu: Extracted Docker-Image: ubuntu:xenialdocker.ubuntu:xenial: Extract from library/ubuntudocker.ubuntu: Zusammenfassung: sha256:eed7e1076bbc1f342c4474c718e5438af4784f59a4e88ad687dbb98483b59ee4docker.ubuntu: Status: Image is up to date for ubuntu: xenialdocker.ubuntu: docker.io/library/ubuntu:xenial==> docker.ubuntu: starting the docker container...docker.ubuntu: run the command: docker run -v /Users/youruser/.packer.d/tmp051358398:/packer-files -d -i -t --entrypoint=/bin/sh -- ubuntu:xenialdocker.ubuntu: ID continúa: e2e739467b24f21d113d37cf1dd709a8038e0f891cc6d34f56e50e229010d9e2==> docker.ubuntu: use Docker Communicator to connect: 172.17.0.3==> docker.ubuntu: Provisionando-com-Shell-Skript: /var/folders/s6/m22_k3p11z104k2vx1jkqr2c0000gp/T/packer-shell915176051docker.ubuntu: Hello world!==> docker.ubuntu: Provisionando-com-Shell-Skript: /var/folders/s6/m22_k3p11z104k2vx1jkqr2c0000gp/T/packer-shell946919744docker.ubuntu: Add file to docker container==> docker.ubuntu: Commit-ContainerDocker.ubuntu: imagen ID: sha256:513c63d6a34abaf658faf709ad6e3bf24c07f232be1fec7e7aa2ef5a00f11921==> docker.ubuntu: Matando o contenido: e2e739467b24f21d113d37cf1dd709a8038e0f891cc6d34f56e50e229010d9e2==> docker.ubuntu: Post processor running: (type docker-tag)docker.ubuntu (docker-tag): marcando una imagen: sha256:513c63d6a34abaf658faf709ad6e3bf24c07f232be1fec7e7aa2ef5a00f11921docker.ubuntu (docker-tag): Repositorio: learn-packer:ubuntu-xenialCompilation of 'docker.ubuntu' completed in 19 seconds and 647 milliseconds.==> Timeout ended after 19 seconds 648 milliseconds==> Constructions completed. Artifacts from successful builds are:--> docker.ubuntu: Imagen importada de Docker: sha256:513c63d6a34abaf658faf709ad6e3bf24c07f232be1fec7e7aa2ef5a00f11921--> docker.ubuntu: Docker-Image import: learn-packer:ubuntu-xenial with learn-packer:ubuntu-xenial-Tags
at the exit you will findAdd file to Docker container
this confirms that Packer executed the second block of stages.
==> docker.ubuntu: Provisionando-com-Shell-Skript: /var/folders/s6/m22_k3p11z104k2vx1jkqr2c0000gp/T/packer-shell946919744docker.ubuntu: Add file to docker container
Check the docker image
Number the images to verify that Packer tagged the image correctly.
ps Docker Learn-Packer imagesID OF THE REPOSITORY TAG CREATED IMAGE SIZELearn-Packer ubuntu-xenial 513c63d6a34a in 2 minutes 134 MB
To verify that the vendor created theexample.txt
File in the new image, first start the newly created Docker image. SubstituteIMAGE_ID
with the value shown above in your terminal (your local equivalent of513c63d6a34a
as shown in the previous output).
ps docker run -it IMAGE_ID
In the Docker container shell, print the contents of theexample.txt
Archive. this should come backFOO is hello world
as expected.
ps gatosexample.txtFOO is hello world
typesalida
get out of the container.
ps salida
In this tutorial, you updated a Packer JSON template for HCL2. It then added provisioners and post processors to the updated HCL2 model.
For more information on the concepts covered in this tutorial, see the following resources:
- Read more abouthcl2_upgrade commandmiPacker-HCL2-Sintaxis.
- Read more aboutboot command.
- learn howInfrastructure provisioning with Packer and Terraform.
- Learn more about why Packer switched from JSON to HCL2 atHashiCorp packager with HCL configurationBlog entry.