Revoke an artifact and its descendants using inherited revocation
If one of your artifacta has a vulnerability, you may need to revoke it to prevent infrastructure deployments from using it. If Packer builds use the artifact as a parent or source artifact, you may need to revoke its descendants too. HashiCorp Cloud Platform (HCP) Packer lets you revoke an artifact version and, optionally, all of its descendant artifacts.
In this tutorial you will build parent and child artifacts, and store metadata about their relationship in HCP Packer. You will then deploy the child artifacts to AWS using HCP Terraform, revoke a parent artifact and all its descendants, and observe the downstream impact to the HCP Terraform workflow, enforced by an HCP Packer run task.
Note
HCP Terraform Free Edition includes one run task integration that you can apply to up to ten workspaces. Refer to HCP Terraform pricing for details.
In an ideal world, you would rarely revoke an artifact version, and instead "fail forward" by building a new artifact and launching new infrastructure from it. However, building new artifacts takes time, and often the first priority in a security incident is to reduce the impact of a vulnerable artifact. In those situations, you may want to revoke an artifact to prevent new deployments while you work on a resolution.
Prerequisites
This tutorial assumes that you are familiar with the workflows for Packer and HCP Packer. If you are new to Packer, complete the Get Started tutorials first. If you are new to HCP Packer, complete the Get Started HCP Packer tutorials first.
This tutorial also assumes that you are familiar with the workflows for Terraform and HCP Terraform. If you are new to Terraform, complete the Get Started tutorials first. If you are new to HCP Terraform, complete the HCP Terraform Get Started tutorials.
For this tutorial, you will need:
- Packer 1.10.1+ installed locally
- An HCP account with an HCP Packer Registry
- Terraform v1.3+ installed locally
- an HCP Terraform account and organization
- HCP Terraform locally authenticated
Now, create a new HCP service principal and set the following environment variables locally.
Environment Variable | Description |
---|---|
HCP_CLIENT_ID | The client ID generated by HCP when you created the HCP Service Principal |
HCP_CLIENT_SECRET | The client secret generated by HCP when you created the HCP Service Principal |
HCP_ORGANIZATION_ID | Find this in the URL of the HCP Overview page, https://portal.cloud.hashicorp.com/orgs/ORGANIZATION_ID/projects/xxxx |
HCP_PROJECT_ID | Find this in the URL of the HCP Overview page, https://portal.cloud.hashicorp.com/orgs/xxxx/projects/PROJECT_ID |
You will also need an AWS account with credentials set as local environment variables.
Environment Variable | Description |
---|---|
AWS_ACCESS_KEY_ID | The access key ID from your AWS key pair |
AWS_SECRET_ACCESS_KEY | The secret access key from your AWS key pair |
Set your HCP Terraform organization name as an environment variable too.
Environment Variable | Description |
---|---|
TF_CLOUD_ORGANIZATION | The name of your HCP Terraform organization |
Clone example repository
Clone the example repository, which contains the Packer templates and Terraform configuration used in this tutorial.
Change into the repository directory.
Build artifacts
To save time, this tutorial uses a shell script to build several Packer artifacts and assign them to HCP Packer channels.
Open packer/build-and-assign.sh
in your editor. The script first checks that you have set the necessary environment variables.
The script then declares a function that assigns the latest version in a bucket to the specified HCP Packer channel. The function creates the channel if it does not exist.
Next, the script authenticates with the HCP API using the HCP_CLIENT_ID
and HCP_CLIENT_SECRET
environment variables, and stores the returned bearer token in the bearer
variable for future API calls.
Then, it initializes Packer, builds both parent artifacts in parallel, and waits for both to finish before proceeding.
After Packer finishes building the parent artifacts, the script assigns them to their respective production
channels. Then it builds the child artifact and assigns the version to the child bucket's production
channel.
Change into the packer
directory.
Run the script. It may take up to 20 minutes to finish building. Continue with the tutorial while it runs.
Review packer templates
While the artifacts build, open packer/parent-east.pkr.hcl
in your editor to review the first parent artifact template.
The template declares an amazon-ami
data source which returns the latest Ubuntu 22.04 AMI in the us-east-2
region.
The amazon-ebs
source block uses the Ubuntu AMI as the source for the build.
Packer then records the artifact's metadata in the learn-revocation-parent-us-east-2
HCP Packer bucket.
The parent-west.pkr.hcl
file follows the same pattern, but for the us-west-2
region.
This tutorial uses separate Packer templates for each of the parent artifact regions. However, the child template builds artifacts in each region using a single template. While you could define both parent artifacts in a shared template as well, this tutorial defines them separately for the purposes of demonstration. Later in the tutorial you will review how revoking just one of the parent artifacts cascades to the child artifact.
Now, open and review packer/child.pkr.hcl
.
First, the template uses the hcp-packer-version
and hcp-packer-artifact
data sources to fetch metadata about both parent artifacts from HCP Packer. The metadata includes AWS AMI IDs for the us-east-2
and us-west-2
regions.
The amazon-ebs
source blocks use the respective AMIs as the sources for the build.
Finally, Packer records the child artifact metadata in the learn-revocation-child
bucket.
Review Terraform configuration
Now, open terraform/main.tf
. This configuration creates two virtual machines using your child artifact.
First, the configuration uses the hcp_packer_version
data source to fetch artifact metadata from the learn-revocation-child
bucket's production
channel.
It then uses the hcp_packer_artifact
data source to query the version for the us-east-2
AMI ID.
Next, it uses the AWS VPC module to create a VPC, subnets, and a route table in the us-east-2
region.
Finally, the configuration creates a virtual machine from the us-east-2
child AMI.
The configuration then defines the same resources for the us-west-2
region.
Review builds and channel assignments
After Packer finishes building the artifacts, visit the HCP Packer Overview page in HCP.
Review the Versions pages for the learn-revocation-parent-us-east-2
, learn-revocation-parent-us-west-2
, and learn-revocation-child
buckets you created. Notice that the script assigned the latest version to the production
channel of each bucket.
Configure HCP Terraform
Now, prepare your HCP Terraform workspace to deploy infrastructure.
First, change to the terraform
directory.
Set the TF_CLOUD_ORGANIZATION
environment variable to your HCP Terraform
organization name.
Now, initialize your HCP Terraform workspace.
Create HCP Packer run task
Now, create an HCP Terraform Run Task for HCP Packer, which blocks terraform apply
s that would create new infrastructure using revoked artifacts.
Navigate to the HCP Packer dashboard, open the Integrate with HCP Terraform menu, and copy the Endpoint URL and HMAC Key values.
In your HCP Terraform Organization's Settings, create a run task named HCP-Packer
. Configure it with the Endpoint URL and HMAC key values from the HCP Packer dashboard. For more detailed instructions, refer to our run task tutorial.
After you create the run task, associate it with your workspace. Go to Settings for the learn-hcp-packer-revocation
workspace, then select Run Tasks. Select HCP-Packer from the list of Available Run Tasks, then choose the Post-plan stage, and the Mandatory enforcement level. Click Create.
Configure workspace variables
Next, navigate to the learn-hcp-packer-revocation
workspace's Variables page.
Set the following workspace-specific variables. Be sure to use the environment variable type and mark the secrets as sensitive.
Type | Variable name | Description | Sensitive |
---|---|---|---|
Environment variable | AWS_ACCESS_KEY_ID | The access key ID from your AWS key pair | No |
Environment variable | AWS_SECRET_ACCESS_KEY | The secret access key from your AWS key pair | Yes |
Environment variable | HCP_CLIENT_ID | The client ID generated by HCP when you created the HCP Service Principal | No |
Environment variable | HCP_CLIENT_SECRET | The client secret generated by HCP when you created the HCP Service Principal | Yes |
Environment variable | HCP_PROJECT_ID | The ID of your HCP project | No |
Deploy infrastructure
Apply the Terraform configuration to create infrastructure that uses the child artifacts. Respond yes
to the prompt to confirm the operation.
Revoke parent artifact and descendants
Imagine that you find a vulnerability in one of the parent artifacts. If you have time you could avoid disrupting downstream teams by reassigning the channels to secure artifacts before revoking the vulnerable ones. (Those secure artifacts could be newly-patched or previous-good versions depending on your workflow.) But, since resolving vulnerabilities can take a long time and the incident might require an immediate response, you may need to revoke vulnerable artifacts before you have safe replacements, to prevent new deployments of the artifact.
In this tutorial, you will revoke an artifact without building a replacement or reassigning channels to a known-good version, to explore how revocation can impact downstream teams' Terraform workflows.
Warning
Revoking an artifact does not modify or replace infrastructure that uses it.
To revoke an artifact version, you must first remove it from all channels.
In HCP Packer, navigate to the learn-revocation-parent-us-east-2
bucket, then to its Channels.
Hover over the production channel and click the ... menu that appears, then click Change assigned version.
Select Choose a version from the dropdown menu to unassign the version. Click Update channel.
Now navigate to Versions, open the latest version's ... menu, and click Revoke Version.
Select Revoke immediately if your organization purchased the HCP Packer Plus tier. Then, enter a reason for the revocation. Under Revoke descendants, select Yes,revoke all descendants. Next, under Rollback channels, select No, do not rollback channel, then click Revoke. HCP Packer revoked this artifact, but it may take a few minutes for the revocation to cascade to its descendants.
Open the HCP Packer dashboard. Locate the learn-revocation-parent-us-east-2
and learn-revocation-child
artifacts. After a few minutes, the Status column for each shows Revoked.
Open the learn-packer-child
bucket. Under Bucket details, HCP Packer lists the newest version as Revoked.
Navigate to the bucket's Versions, then click the ID of the revoked version. The banner lists the revocation date, reason, and which user triggered it.
Modify infrastructure using the revoked artifact
The child artifact's production
channel still references a revoked version, which will prevent Terraform from replacing or creating new EC2 instances.
Open terraform/main.tf
and change the instance_type
of the aws_instance.west
resource to t3.small
.
Apply the configuration change. Respond yes
to the prompt to confirm the operation.
The HCP Packer run task identified two resources using revoked artifacts but did not block the apply. The run task prevents the creation of new resources, but will not block operations on existing infrastructure.
Now, modify the configuration to trigger a resource replacement.
In terraform/main.tf
, change the subnet of EC2 instance, which is a destructive change.
Now, attempt to apply the configuration change. The HCP Packer run task blocks the change because it creates a new resource using a revoked artifact.
You could also use custom conditions in your Terraform configuration to check the revoke_at
attribute of the hcp_packer_version
or hcp_packer_artifact
data sources. But, custom conditions are easy to remove and require that all configuration authors use them. The HCP Packer run task is a more robust way to prevent using revoked artifacts since it automatically applies to all configuration in the workspace.
Destroy infrastructure and clean up
In the terraform
directory, destroy the infrastructure you created in this tutorial. Respond yes
to the prompt to confirm the operation.
Clean up HCP Terraform resources
Navigate to your learn-packer-revocation
workspace in HCP Terraform and delete the workspace.
Clean up HCP Packer
Navigate to the HCP Packer dashboard.
Locate the learn-revocation-child
artifact and open the ... menu. Select Delete bucket.
Repeat for the learn-revocation-parent-us-east-2
and learn-revocation-parent-us-west-2
buckets.
Delete AWS AMIs
Your AWS account still has AMIs and their respective snapshots, which you may incur charges.
In the us-east-2
AWS region, deregister the learn-revocation AMIs
by selecting them, clicking the Actions button, then the Deregister AMI
option. Finally, confirm by clicking the Deregister AMI button in the
confirmation dialog.
Delete the learn-revocation snapshots by selecting the snapshots, clicking on the Actions button, then the Delete snapshot option, and finally confirm by clicking the Delete button in the confirmation dialog.
Repeat the above steps for the us-west-2
region.
Next Steps
In this tutorial you used HCP Packer to revoke a parent artifact and all descendant artifacts built from it. You also used the HCP Packer run task to prevent new deployments of revoked artifacts and reviewed how revocation can impact team workflows.
For more information on topics covered in this tutorial, check out the following resources.
- Complete the Build a Golden Image Pipeline with HCP Packer tutorial to build a sample application with a golden image pipeline, and deploy it to AWS using Terraform.
- Complete the Schedule artifact version revocation for compliance tutorial to learn how to schedule artifact revocations and use preconditions to prevent use of revoked artifacts outside of HCP Terraform.
- Review the Standardize Machine Images Across Multiple Cloud Providers tutorial to learn how to build consistent machine images across cloud providers.