• HashiCorp Developer

  • HashiCorp Cloud Platform
  • Terraform
  • Packer
  • Consul
  • Vault
  • Boundary
  • Nomad
  • Waypoint
  • Vagrant
Packer
  • Install
  • Tutorials
  • Documentation
  • Guides
  • Plugins
  • Try Cloud(opens in new tab)
  • Sign up
HCP Packer

Skip to main content
5 tutorials
  • Schedule Image Iteration Revocation for Compliance
  • Set Up Terraform Cloud Run Task for HCP Packer
  • Identify Compromised Images with Terraform Cloud
  • Enforce Image Compliance with Terraform Cloud
  • Revoke an Image and its Descendants using Inherited Revocation

  • Resources

  • Tutorial Library
  • Community Forum
    (opens in new tab)
  • Support
    (opens in new tab)
  • GitHub
    (opens in new tab)
  1. Developer
  2. Packer
  3. Tutorials
  4. HCP Packer
  5. Revoke an Image and its Descendants using Inherited Revocation

Revoke an Image and its Descendants using Inherited Revocation

  • 20min

  • HCPHCP
  • PackerPacker
  • TerraformTerraform

If one of your machine images has a vulnerability, you may need to revoke it to prevent infrastructure deployments from using it. If Packer builds use the image as a parent or source image, you may need to revoke its descendants too. HashiCorp Cloud Platform (HCP) Packer lets you revoke an image iteration and, optionally, all of its descendant images.

In this tutorial you will build parent and child images, and store metadata about their relationship in HCP Packer. You will then deploy the child images to AWS using Terraform Cloud, revoke a parent image and all its descendants, and observe the downstream impact to the Terraform Cloud workflow, enforced by an HCP Packer run task.

In an ideal world, you would rarely revoke an image iteration, and instead "fail forward" by building a new image and launching new infrastructure from it. However, building new images takes time, and often the first priority in a security incident is to reduce the impact of a vulnerable image. In those situations, you may want to revoke an image 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 Terraform Cloud. If you are new to Terraform, complete the Get Started tutorials first. If you are new to Terraform Cloud, complete the Terraform Cloud Get Started tutorials.

For this tutorial, you will need:

  • Packer 1.7.10+ installed locally
  • An HCP account with an HCP Packer Registry
  • Terraform v1.3+ installed locally
  • a Terraform Cloud account and organization, with the Team & Governance tier
  • Terraform Cloud locally authenticated

Now, create a new HCP service principal and set the following environment variables locally.

Environment VariableDescription
HCP_CLIENT_IDThe client ID generated by HCP when you created the HCP Service Principal
HCP_CLIENT_SECRETThe client secret generated by HCP when you created the HCP Service Principal
HCP_ORGANIZATION_IDFind this in the URL of the HCP Overview page, https://portal.cloud.hashicorp.com/orgs/ORGANIZATION_ID/projects/xxxx
HCP_PROJECT_IDFind 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 VariableDescription
AWS_ACCESS_KEY_IDThe access key ID from your AWS key pair
AWS_SECRET_ACCESS_KEYThe secret access key from your AWS key pair

Set your Terraform Cloud organization name as an environment variable too.

Environment VariableDescription
TF_CLOUD_ORGANIZATIONThe name of your Terraform Cloud organization

Clone example repository

Clone the example repository, which contains the Packer templates and Terraform configuration used in this tutorial.

$ git clone https://github.com/hashicorp-education/learn-hcp-packer-revocation.git

Change into the repository directory.

$ cd learn-hcp-packer-revocation

Build images

To save time, this tutorial uses a shell script to build several Packer images 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.

packer/build-and-assign.sh
#!/bin/bash

set -eEo pipefail

# Usage check
if [[ -z "$HCP_CLIENT_ID" || -z "$HCP_CLIENT_SECRET" || -z "$HCP_ORGANIZATION_ID" || -z "$HCP_PROJECT_ID" ]]; then
  cat <<EOF
This script requires the following environment variables to be set:
 - HCP_CLIENT_ID
 - HCP_CLIENT_SECRET
 - HCP_ORGANIZATION_ID
 - HCP_PROJECT_ID
EOF
  exit 1
fi

## ...

The script then declares a function that assigns the latest iteration in a bucket to the specified HCP Packer channel. The function creates the channel if it does not exist.

packer/build-and-assign.sh
## ...

update_channel() {
  bucket_slug=$1
  channel_name=$2
  base_url="https://api.cloud.hashicorp.com/packer/2021-04-30/organizations/$HCP_ORGANIZATION_ID/projects/$HCP_PROJECT_ID"

  # Fetch bucket iterations
  response=$(curl --request GET --silent \
    --url "$base_url/images/$bucket_slug/iterations" \
    --header "authorization: Bearer $bearer")
  api_error=$(echo "$response" | jq -r '.message')
  if [ "$api_error" != null ]; then
    # Failed to list iterations
    echo "Failed to list iterations: $api_error"
    exit 1
  else
    iteration_id=$(echo "$response" | jq -r '.iterations[0].id')
  fi

  # Ensure channel exists
  response=$(curl --request GET --silent \
    --url "$base_url/images/$bucket_slug/channels/$channel_name" \
    --header "authorization: Bearer $bearer")
  api_error=$(echo "$response" | jq -r '.message')
  if [ "$api_error" != null ]; then
    # Channel likely doesn't exist, create it
    api_error=$(curl --request POST --silent \
      --url "$base_url/images/$bucket_slug/channels" \
      --data-raw '{"slug":"'"$channel_name"'"}' \
      --header "authorization: Bearer $bearer" | jq -r '.error')
    if [ "$api_error" != null ]; then
      echo "Error creating channel: $api_error"
      exit 1
    fi
  fi

  # Update channel to point to iteration
  api_error=$(curl --request PATCH --silent \
    --url "$base_url/images/$bucket_slug/channels/$channel_name" \
    --data-raw '{"iteration_id":"'"$iteration_id"'"}' \
    --header "authorization: Bearer $bearer" | jq -r '.message')
  if [ "$api_error" != null ]; then
      echo "Error updating channel: $api_error"
      exit 1
  fi
}

## ...

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.

packer/build-and-assign.sh
## ...

# Authenticate and get bearer token for subsequent API calls
response=$(curl --request POST --silent \
  --url 'https://auth.hashicorp.com/oauth/token' \
  --data grant_type=client_credentials \
  --data client_id="$HCP_CLIENT_ID" \
  --data client_secret="$HCP_CLIENT_SECRET" \
  --data audience="https://api.hashicorp.cloud")
api_error=$(echo "$response" | jq -r '.error')
if [ "$api_error" != null ]; then
  echo "Failed to get access token: $api_error"
  exit 1
fi
bearer=$(echo "$response" | jq -r '.access_token')

## ...

Then, it initializes Packer, builds both parent images in parallel, and waits for both to finish before proceeding.

packer/build-and-assign.sh
## ...

packer init parent-east.pkr.hcl

echo "Building parent images"
export HCP_PACKER_BUILD_FINGERPRINT=$(date +%s)
packer build parent-east.pkr.hcl &
packer build parent-west.pkr.hcl &
wait

## ...

After Packer finishes building the parent images, the script assigns them to their respective production channels. Then it builds the child image and assigns the iteration to the child bucket's production channel.

packer/build-and-assign.sh
## ...

echo "SETTING US-EAST-2 PARENT CHANNEL"
bucket_slug="learn-revocation-parent-us-east-2"
update_channel $bucket_slug production

echo "SETTING US-WEST-2 PARENT CHANNEL"
bucket_slug="learn-revocation-parent-us-west-2"
update_channel $bucket_slug production

echo "BUILDING CHILD IMAGE"
export HCP_PACKER_BUILD_FINGERPRINT=$(date +%s)
packer build child.pkr.hcl
echo "SETTING CHILD CHANNEL"
bucket_slug="learn-revocation-child"
update_channel $bucket_slug production

Change into the packer directory.

$ cd packer

Run the script. It may take up to 20 minutes to finish building. Continue with the tutorial while it runs.

$ ./build-and-assign.sh

Building parent images
amazon-ebs.west: output will be in this color.

amazon-ebs.east: output will be in this color.

==> amazon-ebs.east: Prevalidating any provided VPC information
==> amazon-ebs.east: Prevalidating AMI Name: learn-revocation-parent-1673448026
==> amazon-ebs.west: Prevalidating any provided VPC information
==> amazon-ebs.west: Prevalidating AMI Name: learn-revocation-parent-1673448026

## ...

Build 'amazon-ebs.east' finished after 3 minutes 6 seconds.

==> Wait completed after 3 minutes 6 seconds

==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs.east: AMIs were created:
us-east-2: ami-076c3398b68132353

--> amazon-ebs.east: Published metadata to HCP Packer registry packer/learn-revocation-parent-us-east-2/iterations/01GPGMCW3SQCHPW84VT0NV31RZ

## ...

--> amazon-ebs.west: Published metadata to HCP Packer registry packer/learn-revocation-parent-us-west-2/iterations/01GPGMCWAHX0Y0G9BNFXZ3A2EG
SETTING US-EAST-2 PARENT CHANNEL
SETTING US-WEST-2 PARENT CHANNEL
BUILDING CHILD IMAGE
amazon-ebs.child-east: output will be in this color.
amazon-ebs.child-west: output will be in this color.

==> amazon-ebs.child-east: Prevalidating any provided VPC information
==> amazon-ebs.child-east: Prevalidating AMI Name: learn-revocation-child-1673448644
==> amazon-ebs.child-west: Prevalidating any provided VPC information
==> amazon-ebs.child-west: Prevalidating AMI Name: learn-revocation-child-1673448644

## ...

Build 'amazon-ebs.child-east' finished after 4 minutes 39 seconds.

==> Wait completed after 4 minutes 39 seconds

==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs.child-west: AMIs were created:
us-west-2: ami-0c329c7e2a97e7c70

--> amazon-ebs.child-west: Published metadata to HCP Packer registry packer/learn-revocation-child/iterations/01GPGMZQ7V42JDSCAQQ9HK9XSE
--> amazon-ebs.child-east: AMIs were created:
us-east-2: ami-0bd3fa72578a11378

--> amazon-ebs.child-east: Published metadata to HCP Packer registry packer/learn-revocation-child/iterations/01GPGMZQ7V42JDSCAQQ9HK9XSE
SETTING CHILD CHANNEL
DONE

Review packer templates

While the images build, open packer/parent-east.pkr.hcl in your editor to review the first parent image template.

packer/parent-east.pkr.hcl
data "amazon-ami" "ubuntu" {
  region = "us-east-2"
  filters = {
    name = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
  }
  most_recent = true
  owners      = ["099720109477"]
}

The template declares an amazon-ami data source which returns the latest Ubuntu 22.04 AMI in the us-east-2 region.

packer/parent-east.pkr.hcl
## ...
source "amazon-ebs" "east" {
  ami_name       = "learn-revocation-parent-{{timestamp}}"
  region         = "us-east-2"
  source_ami     = data.amazon-ami.ubuntu.id
  instance_type  = "t2.small"
  ssh_username   = "ubuntu"
  ssh_agent_auth = false
  tags = {
    Name = "learn-revocation-parent"
  }
}

The amazon-ebs source block uses the Ubuntu AMI as the source for the build.

packer/parent-east.pkr.hcl
## ...
build {
  hcp_packer_registry {
    bucket_name = "learn-revocation-parent-us-east-2"
  }
  sources = [
    "source.amazon-ebs.east"
  ]
}

Packer then records the image'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 image regions. However, the child template builds images in each region using a single template. While you could define both parent images 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 images cascades to the child image.

Now, open and review packer/child.pkr.hcl.

packer/child.pkr.hcl
data "hcp-packer-iteration" "parent-east" {
  bucket_name = "learn-revocation-parent-us-east-2"
  channel     = "production"
}

data "hcp-packer-image" "parent-east" {
  bucket_name    = data.hcp-packer-iteration.parent-east.bucket_name
  iteration_id   = data.hcp-packer-iteration.parent-east.id
  cloud_provider = "aws"
  region         = "us-east-2"
}

data "hcp-packer-iteration" "parent-west" {
  bucket_name = "learn-revocation-parent-us-west-2"
  channel     = "production"
}

data "hcp-packer-image" "parent-west" {
  bucket_name    = data.hcp-packer-iteration.parent-west.bucket_name
  iteration_id   = data.hcp-packer-iteration.parent-west.id
  cloud_provider = "aws"
  region         = "us-west-2"
}
## ...

First, the template uses the hcp-packer-iteration and hcp-packer-image data sources to fetch metadata about both parent images from HCP Packer. The metadata includes AWS AMI IDs for the us-east-2 and us-west-2 regions.

packer/child.pkr.hcl
## ...
source "amazon-ebs" "child-east" {
  ami_name       = "learn-revocation-child-{{timestamp}}"
  region         = "us-east-2"
  source_ami     = data.hcp-packer-image.parent-east.id
  instance_type  = "t2.small"
  ssh_username   = "ubuntu"
  ssh_agent_auth = false
  tags = {
    Name = "learn-revocation-child"
  }
}

source "amazon-ebs" "child-west" {
  ami_name       = "learn-revocation-child-{{timestamp}}"
  region         = "us-west-2"
  source_ami     = data.hcp-packer-image.parent-west.id
  instance_type  = "t2.small"
  ssh_username   = "ubuntu"
  ssh_agent_auth = false
  tags = {
    Name = "learn-revocation-child"
  }
}
## ...

The amazon-ebs source blocks use the respective AMIs as the sources for the build.

packer/child.pkr.hcl
## ...
build {
  hcp_packer_registry {
    bucket_name = "learn-revocation-child"
  }
  sources = [
    "source.amazon-ebs.child-east",
    "source.amazon-ebs.child-west"
  ]
}

Finally, Packer records the child image metadata in the learn-revocation-child bucket.

Review Terraform configuration

Now, open terraform/main.tf. This configuration creates two virtual machines using your child image.

terraform/main.tf
data "hcp_packer_iteration" "child" {
  bucket_name = "learn-revocation-child"
  channel     = "production"
}
## ...

First, the configuration uses the hcp_packer_iteration data source to fetch image metadata from the learn-revocation-child bucket's production channel.

terraform/main.tf
## ...
# us-east-2 region resources
data "hcp_packer_image" "aws_east" {
  bucket_name    = data.hcp_packer_iteration.child.bucket_name
  iteration_id   = data.hcp_packer_iteration.child.ulid
  cloud_provider = "aws"
  region         = "us-east-2"
}
## ...

It then uses the hcp_packer_image data source to query the iteration for the us-east-2 AMI ID.

terraform/main.tf
## ...
module "vpc_east" {
  source = "terraform-aws-modules/vpc/aws"
  providers = {
    aws = aws.east
  }

  name            = "learn-revocation-east"
  cidr            = "10.1.0.0/16"
  azs             = ["us-east-2a"]
  private_subnets = ["10.1.1.0/24", "10.1.2.0/24"]
}
## ...

Next, it uses the AWS VPC module to create a VPC, subnets, and a route table in the us-east-2 region.

terraform/main.tf
## ...
resource "aws_instance" "east" {
  provider                    = aws.east
  ami                         = data.hcp_packer_image.aws_east.cloud_image_id
  instance_type               = "t3.micro"
  subnet_id                   = module.vpc_east.private_subnets[0]
  vpc_security_group_ids      = [module.vpc_east.default_security_group_id]
  associate_public_ip_address = false

  tags = {
    Name = "learn-revocation-us-east-2"
  }
}
## ...

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 images, visit the HCP Packer Overview page in HCP.

Review the Iterations 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 iteration to the production channel of each bucket.

Configure Terraform Cloud

Now, prepare your Terraform Cloud workspace to deploy infrastructure.

First, change to the terraform directory.

$ cd ../terraform

Now, initialize your Terraform Cloud workspace.

$ terraform init
##...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Create HCP Packer run task

Now, create a Terraform Cloud Run Task for HCP Packer, which blocks terraform applys that would create new infrastructure using revoked images.

Navigate to the HCP Packer dashboard, open the Integrate with Terraform Cloud menu, and copy the Endpoint URL and HMAC Key values.

In your Terraform Cloud 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.

TypeVariable nameDescriptionSensitive
Environment variableAWS_ACCESS_KEY_IDThe access key ID from your AWS key pairNo
Environment variableAWS_SECRET_ACCESS_KEYThe secret access key from your AWS key pairYes
Environment variableHCP_CLIENT_IDThe client ID generated by HCP when you created the HCP Service PrincipalNo
Environment variableHCP_CLIENT_SECRETThe client secret generated by HCP when you created the HCP Service PrincipalYes

Deploy infrastructure

Apply the Terraform configuration to create infrastructure that uses the child images. Respond yes to the prompt to confirm the operation.

$ terraform apply
Running apply in Terraform Cloud. Output will stream here. Pressing Ctrl-C
will cancel the remote apply if it's still pending. If the apply started it
will stop streaming the logs, but will not stop the apply running remotely.

Preparing the remote apply...

To view this run in a browser, visit:
https://app.terraform.io/app/hashicorp-learn/learn-packer-multicloud/runs/run-000

Waiting for the plan to start...

Terraform v1.1.6
on linux_amd64
Initializing plugins and modules...
data.hcp_packer_iteration.child: Reading...
data.hcp_packer_iteration.child: Read complete after 0s [id=01GPC1VWC8YAN9T85TXK4TS06S]
data.hcp_packer_image.aws_west: Reading...
data.hcp_packer_image.aws_east: Reading...
data.hcp_packer_image.aws_east: Read complete after 0s [id=01GPC21QKAYBVG6V54NMKGKKAC]
data.hcp_packer_image.aws_west: Read complete after 0s [id=01GPC251E05RS8S86C4JY1R8MW]

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

## ...

Plan: 16 to add, 0 to change, 0 to destroy.


Post-plan Tasks:

1 tasks still pending, 0 passed, 0 failed ...    (8s elapsed)
1 tasks still pending, 0 passed, 0 failed ...    (18s elapsed)
1 tasks still pending, 0 passed, 0 failed ...    (31s elapsed)
All tasks completed! 1 passed, 0 failed           (39s elapsed)

│ HCP-Packer ⸺   Passed
│ Data source and resource image validation results: 2 resources scanned. All resources are compliant.
│ Details: https://portal.cloud.hashicorp.com/services/packer?project_id=XXXX
│
│
│ Overall Result: Passed

------------------------------------------------------------------------


Do you want to perform these actions in workspace "learn-hcp-packer-revocation"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

## ...

Apply complete! Resources: 16 added, 0 changed, 0 destroyed.

Revoke parent image and descendants

Imagine that you find a vulnerability in one of the parent images. If you have time you could avoid disrupting downstream teams by reassigning the channels to secure images before revoking the vulnerable ones. (Those secure images 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 images before you have safe replacements, to prevent new deployments of the image.

In this tutorial, you will revoke an image without building a replacement or reassigning channels to a known-good iteration, to explore how revocation can impact downstream teams' Terraform workflows.

Warning: Revoking an image does not modify or replace infrastructure that uses it.

To revoke an image iteration, 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 iteration.

Select Choose an iteration from the dropdown menu to unassign the iteration. Click Update channel.

Now navigate to Iterations, open the latest iteration's ... menu, and click Revoke Iteration.

Select Revoke immediately if your organization purchased the HCP Packer Plus tier. Then, enter a reason for the revocation, and click Next.

On the next page, select Revoke all descendants, type REVOKE, and click Revoke. HCP Packer revoked this image, but it may take a few minutes for the revocation to cascade to its descendants.

Revoke iteration

Open the HCP Packer dashboard. Locate the learn-revocation-parent-us-east-2 and learn-revocation-child images. After a few minutes, the Status column for each shows Revoked.

Open the learn-packer-child bucket. Under Image details, HCP Packer lists the newest iteration as Revoked.

Navigate to the bucket's Iterations, then click the ID of the revoked iteration. The banner lists the revocation date, reason, and which user triggered it.

Modify infrastructure using the revoked image

The child image's production channel still references a revoked iteration, 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.

terraform/main.tf
## ...
resource "aws_instance" "west" {
  provider                    = aws.west
  ami                         = data.hcp_packer_image.aws_west.cloud_image_id
  instance_type               = "t3.small"
  subnet_id                   = module.vpc_west.private_subnets[0]
  vpc_security_group_ids      = [module.vpc_west.default_security_group_id]
  associate_public_ip_address = false

  tags = {
    Name = "learn-revocation-us-west-2"
  }
}

Apply the configuration change. Respond yes to the prompt to confirm the operation.

$ terraform apply

## ...

Plan: 0 to add, 1 to change, 0 to destroy.


Post-plan Tasks:

1 tasks still pending, 0 passed, 0 failed ...    (7s elapsed)
1 tasks still pending, 0 passed, 0 failed ...    (18s elapsed)
1 tasks still pending, 0 passed, 0 failed ...    (30s elapsed)
All tasks completed! 1 passed, 0 failed           (36s elapsed)

│ HCP-Packer ⸺   Passed
│ Data source and resource image validation results: 2 resources scanned. 
  2 existing resources using revoked images. No newer version was found for 
  the revoked images. Use Packer to build compliant images and send information 
  to HCP Packer. When using channels, the channel must be re-assigned to a valid 
  iteration.
│ Details: https://portal.cloud.hashicorp.com/services/packer?project_id=XXXX
│
│
│ Overall Result: Passed

------------------------------------------------------------------------


Do you want to perform these actions in workspace "learn-hcp-packer-revocation"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

## ...

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

The HCP Packer run task identified two resources using revoked images 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.

terraform/main.tf
## ...
resource "aws_instance" "west" {
  provider                    = aws.west
  ami                         = data.hcp_packer_image.aws_west.cloud_image_id
  instance_type               = "t3.small"
  subnet_id                   = module.vpc_west.private_subnets[1]
  vpc_security_group_ids      = [module.vpc_west.default_security_group_id]
  associate_public_ip_address = false

  tags = {
    Name = "learn-revocation-us-west-2"
  }
}

Now, attempt to apply the configuration change. The HCP Packer run task blocks the change because it creates a new resource using a revoked image.

$ terraform apply

## ...
Plan: 1 to add, 0 to change, 1 to destroy.


Post-plan Tasks:

1 tasks still pending, 0 passed, 0 failed ...    (7s elapsed)
1 tasks still pending, 0 passed, 0 failed ...    (18s elapsed)
1 tasks still pending, 0 passed, 0 failed ...    (30s elapsed)
All tasks completed! 0 passed, 1 failed          (41s elapsed)

│ HCP-Packer ⸺   Failed (Mandatory)
│ Data source and resource image validation results: 2 resources scanned. 
  1 new resource using revoked images. 1 existing resource using revoked images. 
  No newer version was found for the revoked images. Use Packer to build 
  compliant images and send information to HCP Packer. When using channels, the 
  channel must be re-assigned to a valid iteration.
│ Details: https://portal.cloud.hashicorp.com/services/packer?project_id=XXXX
│
│
│ Overall Result: Failed

------------------------------------------------------------------------

â•·
│ Error: the run failed because the run task, HCP-Packer, is required to succeed

You could also use custom conditions in your Terraform configuration to check the revoke_at attribute of the hcp_packer_iteration or hcp_packer_image 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 images 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.

$ terraform destroy
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:
##...
Plan: 0 to add, 0 to change, 16 to destroy.
##...

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes
##...
Destroy complete! Resources: 16 destroyed.

Clean up Terraform Cloud resources

Navigate to your learn-packer-revocation workspace in Terraform Cloud and delete the workspace.

Clean up HCP Packer

Navigate to the HCP Packer dashboard.

Locate the learn-revocation-child image and open the ... menu. Select Delete image bucket.

Repeat for the learn-revocation-parent-us-east-2 and learn-revocation-parent-us-west-2 buckets.

Delete AWS machine images

Your AWS account still has machine images 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 image and all descendant images built from it. You also used the HCP Packer run task to prevent new deployments of revoked images 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 image with a golden image pipeline, and deploy it to AWS using Terraform.
  • Complete the Schedule Image Iteration Revocation for Compliance tutorial to learn how to schedule image revocations and use preconditions to prevent use of revoked images outside of Terraform Cloud.
  • Review the Standardize Machine Images Across Multiple Cloud Providers tutorial to learn how to build consistent machine images across cloud providers.
 Previous
 Next Collection

On this page

  1. Revoke an Image and its Descendants using Inherited Revocation
  2. Prerequisites
  3. Clone example repository
  4. Build images
  5. Review packer templates
  6. Review Terraform configuration
  7. Review builds and channel assignments
  8. Configure Terraform Cloud
  9. Deploy infrastructure
  10. Revoke parent image and descendants
  11. Modify infrastructure using the revoked image
  12. Destroy infrastructure and clean up
  13. Next Steps
Give Feedback(opens in new tab)
  • Certifications
  • System Status
  • Terms of Use
  • Security
  • Privacy
  • Trademark Policy
  • Trade Controls
  • Give Feedback(opens in new tab)