Packer
Track Packer artifact package metadata with HCP Packer
If you discover a vulnerability in a package used by multiple artifacts, you need to know which artifacts to update. A software bill of materials (SBOM) documents which package versions a specific artifact contains, helping teams quickly identify the artifacts they need to update.
HCP Packer lets you store SBOMs for each artifact version. By storing this information with your artifact metadata, you establish a source of truth for exactly what each artifact contains.
In this tutorial, you will modify a Packer template to create an SBOM and upload it to HCP Packer. You will then review how to access this SBOM and use it to identify vulnerabilities, update the artifact, and create a new SBOM.
Prerequisites
This tutorial assumes that you are familiar with the standard Packer and HCP Packer workflows. If you are new to Packer, complete the Get Started tutorials first. If you are new to HCP Packer, complete the Get Started with HCP Packer tutorials first.
To follow along with this tutorial, you will need:
- Packer 1.12+ installed locally.
- An HCP account with the HCP Packer Plus tier.
- An HCP Packer registry.
- Docker Desktop installed locally.
- Trivy 0.58+ installed locally.
Configure HCP service principal
Packer needs service principal credentials to authenticate against HCP and store artifact metadata. In your HCP project's dashboard, go to Access control (IAM) in the left navigation menu, then select the Service principals tab.
Create a service principal named packer
with the Contributor role.
Once you create the service principal, HCP shows you a detailed overview page. Click Keys in the left navigation bar, then click Generate key to create a client ID and secret.
Next, in your terminal, set an environment variable for the client ID.
$ export HCP_CLIENT_ID=
Then, set an environment variable for your client secret.
$ export HCP_CLIENT_SECRET=
Copy these values from HCP Packer. You cannot access these keys after you generate them, so in production, store the keys in a secure location, such as HCP Vault.
Create the Packer template
In this section, you will use a Packer template that creates an Ubuntu Docker container and update it to generate and upload an SBOM.
Create a new directory to store your Packer template.
$ mkdir learn-packer-sbom
Navigate to the new directory.
$ cd learn-packer-sbom
Create a file named docker-ubuntu.pkr.hcl
.
$ touch docker-ubuntu.pkr.hcl
Open the docker-ubuntu.pkr.hcl
file, paste the following HCL, and save the file.
docker-ubuntu.pkr.hcl
variable "image_version" {
type = string
default = "0.1"
}
packer {
required_plugins {
docker = {
version = ">= 1.1.0"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "ubuntu" {
image = "ubuntu:22.04"
commit = true
}
build {
name = "learn-packer-sbom"
sources = [
"source.docker.ubuntu"
]
hcp_packer_registry {
bucket_name = "learn-packer-sbom"
description = "Generate and store a software bill of materials in HCP Packer."
}
# Install curl and ruby
provisioner "shell" {
inline = [
"apt-get update",
"apt-get -y install curl ruby",
]
}
post-processor "docker-tag" {
repository = "learn-packer-sbom"
tags = ["${var.image_version}"]
}
}
This Packer template creates a new Docker container from the ubuntu:22.04
base image, installs curl
and ruby
, and pushes the metadata to HCP Packer. This example Packer template serves as a starting point. In the next section you will generate and upload an SBOM for your template.
Generate the software bill of materials
This tutorial uses Trivy to generate the SBOM, but you can use any tool that can generate SBOMs in a supported format. HCP Packer supports two standardized SBOM formats: CycloneDX and Software Package Data Exchange (SPDX). You must generate these SBOMs as JSON files.
Add the following provisioner
blocks under the existing shell
provisioner to install Trivy and generate the SBOM.
docker-ubuntu.pkr.hcl
# Install trivy
provisioner "shell" {
inline = [
"curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin latest"
]
}
# Run trivy to generate the SBOM
provisioner "shell" {
inline = [
"trivy fs --format cyclonedx --output /tmp/sbom_cyclonedx_${var.image_version}.json /"
]
}
The first provisioner
block downloads and installs the latest version of Trivy. The second provisioner
block runs Trivy to generate an SBOM in the CycloneDX format, storing it in the /tmp
directory inside the container.
Next, add one more provisioner
block to use the hcp-sbom provisioner to upload the SBOM to HCP Packer during your build.
docker-ubuntu.pkr.hcl
# Upload SBOM
provisioner "hcp-sbom" {
source = "/tmp/sbom_cyclonedx_${var.image_version}.json"
destination = "sbom_cyclonedx_${var.image_version}.json"
sbom_name = "sbom-cyclonedx-ubuntu"
}
The hcp-sbom
provisioner uploads the SBOM at the source
path in the container to HCP Packer, uses the sbom_name
to store it in HCP Packer as "sbom-cyclonedx-ubuntu", and associates it with the artifact version. The optional destination
argument saves a copy of the SBOM on the local machine. If you don't supply the optional sbom_name
, Packer uses the build fingerprint as the SBOM name. If your Packer configuration has multiple build sources, Packer uploads an SBOM for each artifact it creates.
Next, initialize the Packer template.
$ packer init .
Then, build the Packer template.
$ packer build .
Tracking build on HCP Packer with fingerprint "01JH8VYRMR3SGYV3Z8QM5D5S5C"
learn-packer-sbom.docker.ubuntu: output will be in this color.
==> learn-packer-sbom.docker.ubuntu: Creating a temporary directory for sharing data...
==> learn-packer-sbom.docker.ubuntu: Pulling Docker image: ubuntu:22.04
##...
==> Wait completed after 31 seconds 542 milliseconds
==> Builds finished. The artifacts of successful builds are:
--> learn-packer-sbom.docker.ubuntu: Imported Docker image: sha256:3c13e916ccaf4e82319ad8bd7aa8f3ae923836da4ff0b59cc5f8f646ae302384
--> learn-packer-sbom.docker.ubuntu: Imported Docker image: learn-packer-sbom:0.1 with tags learn-packer-sbom:0.1
--> learn-packer-sbom.docker.ubuntu: Published metadata to HCP Packer registry packer/learn-packer-sbom/versions/01JH8VYSSHTAGVRDC4WWEGSWQS
Review the software bill of materials
Open the sbom_cyclonedx_0.1.json
file on your local machine and review the contents. This file contains metadata about the operating system, installed packages, and the SBOM itself. For example, the following segment shows information about ruby
, which you installed as a part of the Packer build process.
sbom_cyclonedx_0.1.json
##...
{
"bom-ref": "pkg:deb/ubuntu/ruby3.0@3.0.2-7ubuntu2.8?arch=arm64&distro=ubuntu-22.04",
"type": "library",
"supplier": {
"name": "Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>"
},
"name": "ruby3.0",
"version": "3.0.2-7ubuntu2.8",
"licenses": [
{
##...
}
],
"purl": "pkg:deb/ubuntu/ruby3.0@3.0.2-7ubuntu2.8?arch=arm64&distro=ubuntu-22.04",
"properties": [
{
"name": "aquasecurity:trivy:PkgID",
"value": "ruby3.0@3.0.2-7ubuntu2.8"
},
{
"name": "aquasecurity:trivy:PkgType",
"value": "ubuntu"
},
{
"name": "aquasecurity:trivy:SrcName",
"value": "ruby3.0"
},
{
"name": "aquasecurity:trivy:SrcRelease",
"value": "7ubuntu2.8"
},
{
"name": "aquasecurity:trivy:SrcVersion",
"value": "3.0.2"
}
]
},
##...
Navigate to your learn-packer-sbom
bucket in HCP Packer, click Versions in the left navigation bar, then click the v1 version. This page shows all the metadata of the build, including the Packer plugins, build labels, and Docker information. In the Artifacts section, click the Download SBOMs dropdown to see the SBOM file you uploaded as part of your Packer build named "sbom-cyclonedx-ubuntu".
Scan the SBOM for vulnerabilities
You can use this SBOM to scan your container for vulnerabilities. In your local terminal, use the trivy sbom
command to scan the SBOM you generated.
$ trivy sbom sbom_cyclonedx_0.1.json
2024-12-19T16:47:40-05:00 INFO [vuln] Vulnerability scanning is enabled
2024-12-19T16:47:40-05:00 INFO Detected SBOM format format="cyclonedx-json"
2024-12-19T16:47:40-05:00 INFO Detected OS family="ubuntu" version="22.04"
2024-12-19T16:47:40-05:00 INFO [ubuntu] Detecting vulnerabilities... os_version="22.04" pkg_num=136
2024-12-19T16:47:40-05:00 INFO Number of language-specific files num=3
2024-12-19T16:47:40-05:00 INFO [bundler] Detecting vulnerabilities...
2024-12-19T16:47:40-05:00 INFO [gemspec] Detecting vulnerabilities...
2024-12-19T16:47:40-05:00 WARN Using severities from other vendors for some vulnerabilities. Read https://aquasecurity.github.io/trivy/v0.58/docs/scanner/vulnerability#severity-selection for details.
sbom_cyclonedx_0.1.json (ubuntu 22.04)
Total: 38 (UNKNOWN: 0, LOW: 27, MEDIUM: 11, HIGH: 0, CRITICAL: 0)
##...
Trivy found 11 packages with medium-severity vulnerabilities and 27 low-severity vulnerabilities. By default, Trivy also lists each vulnerability, the package version it affects, if there is a version that contains a fix, and a link to the CVE summary.
In your organization, you can codify this build and scan process in your build pipeline. For example, you can store the SBOM for future reference and audits, and only let the build pass if your security scan succeeds.
Update the Packer template
Next, update your Packer template to use a newer version of Ubuntu which contains fixes for some of the vulnerabilities found in your scan.
In your docker-ubuntu.pkr.hcl
file, update the Ubuntu image tag to 24.04
.
docker-ubuntu.pkr.hcl
source "docker" "ubuntu" {
image = "ubuntu:24.04"
commit = true
}
Run the Packer build again with the -var
flag to set the image_version
variable to 0.2
.
$ packer build -var "image_version=0.2" .
Tracking build on HCP Packer with fingerprint "01JH8WFSTDTF66FAEG9PDCCTWG"
learn-packer-sbom.docker.ubuntu: output will be in this color.
==> learn-packer-sbom.docker.ubuntu: Creating a temporary directory for sharing data...
==> learn-packer-sbom.docker.ubuntu: Pulling Docker image: ubuntu:24.04
##...
==> Wait completed after 31 seconds 257 milliseconds
==> Builds finished. The artifacts of successful builds are:
--> learn-packer-sbom.docker.ubuntu: Imported Docker image: sha256:2ed90326bc8daaed42c96b29a9431fbb24d6e1fa87b6157eda85c6540769ba80
--> learn-packer-sbom.docker.ubuntu: Imported Docker image: learn-packer-sbom:0.2 with tags learn-packer-sbom:0.2
--> learn-packer-sbom.docker.ubuntu: Published metadata to HCP Packer registry packer/learn-packer-sbom/versions/01JH8WFTF4WJ78EWNHE7AP7PRD
Packer stores a copy of the SBOM on your local machine with the file name sbom_cyclonedx_0.2.json
. Run the trivy sbom
command again to scan the SBOM for vulnerabilities.
$ trivy sbom sbom_cyclonedx_0.2.json
2024-12-19T16:58:51-05:00 INFO [vuln] Vulnerability scanning is enabled
2024-12-19T16:58:51-05:00 INFO Detected SBOM format format="cyclonedx-json"
2024-12-19T16:58:51-05:00 INFO Detected OS family="ubuntu" version="24.04"
2024-12-19T16:58:51-05:00 INFO [ubuntu] Detecting vulnerabilities... os_version="24.04" pkg_num=124
2024-12-19T16:58:51-05:00 INFO Number of language-specific files num=0
sbom_cyclonedx_0.2.json (ubuntu 24.04)
Total: 21 (UNKNOWN: 0, LOW: 13, MEDIUM: 8, HIGH: 0, CRITICAL: 0)
##...
Notice that Trivy found fewer vulnerabilities after you upgraded to Ubuntu 24.04.
Clean up your infrastructure
Delete the two Docker containers you built with Packer.
$ docker rmi learn-packer-sbom:0.1 learn-packer-sbom:0.2
Next, remove the HCP Packer bucket you created. In HCP Packer, navigate to your "learn-packer-sbom" bucket, click the Manage dropdown, and click Delete bucket. When HCP Packer prompts you to confirm that you want to delete the bucket, click Delete bucket to remove the two artifacts you built in this tutorial.
Next steps
In this tutorial, you updated a Packer template to generate a software bill of materials, then you uploaded it to HCP Packer with the hcp-sbom
Packer provisioner. You also used an open source SBOM scanning tool to find vulnerabilities in your Packer artifact. You can use this pattern with your own solutions and implement them into your build pipelines.
For more information on topics covered in this tutorial, check out the following resources:
- Read the HCP SBOM provisioner documentation.
- Learn how to build a golden image pipeline with HCP Packer.
- Learn how to automate Packer with GitHub Actions.
- Set up HCP Terraform run task for HCP Packer to enforce compliance when deploying Packer artifacts.