CloudAWS

Build Secure AMIs with cnspec and HashiCorp Packer

Build secure Amazon AMIs by scanning Packer builds with cnspec for vulnerabilities and misconfigurations.

Run security scans during HashiCorp Packer builds using the cnspec Packer plugin by Mondoo. This tutorial covers both unregistered and registered modes.

This tutorial provisions resources that may qualify under the AWS Free Tier. If your account doesn't qualify, Mondoo isn't responsible for charges that you incur.

Prerequisites

Before you begin, be sure you have:

How the cnspec Packer plugin works

The cnspec Packer plugin by Mondoo scans Linux and Windows HashiCorp Packer builds for vulnerabilities and security misconfigurations. It works with any supported Packer builder, including container builders.

Plugin modes

  • Unregistered — Runs without a Mondoo Platform account, providing a baseline scan with minimal configuration. The plugin runs the Linux Security by Mondoo policy on Linux builds and the Windows Security by Mondoo policy on Windows builds. Results are printed to stdout during the build.
  • Registered — Registers the plugin to your Mondoo Platform space using a service account. You can configure custom policies, run CIS benchmarks, and store every build's results in Mondoo Platform.

Vulnerability scanning requires a registered cnspec. Sign up for a free account to enable it.

AWS authentication

Configure AWS credentials with the permissions needed to build AMIs. See Configuring the AWS CLI and the Packer Amazon AMI Builder documentation for the full IAM permission list.

If you don't have IAM user credentials, use one of the alternative methods in the Packer Amazon AMI Builder documentation.

Plugin configuration

The cnspec plugin exposes these options:

  • score_threshold — An integer score threshold. If the scan produces a score below the threshold, the build fails.
  • on_failure = "continue" — Lets the build succeed even when the score is below the threshold.
  • sudo — Enables sudo for checks that need elevated privileges (for example, reading sshd_config). Set sudo { active = true }.
  • asset_name — Override the asset name in Mondoo Platform. Registered mode only.
  • annotations — Custom annotations attached to the build asset. Registered mode only.

Register with Mondoo Platform

To run the cnspec Packer plugin in registered mode, you need a Base64-encoded Mondoo Platform service account.

  1. Navigate to the space in which you want to create a service account.

  2. In the left navigation, select Settings, then select the Service Accounts tab.

  3. Select the purple plus sign to add a new service account.

  4. Provide a Name and (optionally) a Description.

  5. Under Permissions, select Agent, then select Generate Service Account.

  6. Copy the Base64-encoded credentials to your clipboard.

  7. In the terminal where you'll run Packer, export the credentials:

    export MONDOO_CONFIG_BASE64=<paste Base64-encoded token>

Run Packer

Ubuntu 24.04 template

Create a directory and switch to it:

mkdir mondoo_packer
cd mondoo_packer

Create aws-ubuntu2404.pkr.hcl with the following content:

packer {
  required_plugins {
    amazon = {
      version = ">= 1.3.0"
      source  = "github.com/hashicorp/amazon"
    }
    cnspec = {
      version = ">= 12.0.0"
      source  = "github.com/mondoohq/cnspec"
    }
  }
}

variable "aws_region" {
  default = "us-east-1"
  type    = string
}

variable "image_prefix" {
  type        = string
  description = "Prefix to be applied to the image name"
  default     = "cnspec-tested-amazon-ubuntu-2404"
}

locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }

source "amazon-ebs" "ubuntu2404" {
  ami_name      = "${var.image_prefix}-${local.timestamp}"
  instance_type = "t3.micro"
  region        = var.aws_region
  source_ami_filter {
    filters = {
      name                = "ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["099720109477"] # Canonical
  }
  ssh_username = "ubuntu"
  tags = {
    Base_AMI_Name = "{{ .SourceAMIName }}"
    Name          = "${var.image_prefix}-${local.timestamp}"
    Source_AMI    = "{{ .SourceAMI }}"
    Creation_Date = "{{ .SourceAMICreationDate }}"
  }
}

build {
  name = "${var.image_prefix}-${local.timestamp}"

  sources = ["source.amazon-ebs.ubuntu2404"]

  provisioner "shell" {
    inline = [
      "sudo hostnamectl set-hostname ${var.image_prefix}-${local.timestamp}",
      "sudo apt-get update",
      "sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y",
      "sudo apt-get autoremove -y",
      "sudo apt-get clean",
    ]
  }

  provisioner "cnspec" {
    score_threshold = 80
    on_failure      = "continue"
    sudo {
      active = true
    }
  }
}

This template builds an Ubuntu 24.04 AMI in us-east-1. The next sections walk through the variables and run.

Configure template variables

The template exposes three variables:

For the various ways to override Packer variables, see Setting Variables in the HashiCorp Packer documentation.

aws_region — The AWS region for the build. Defaults to us-east-1:

variable "aws_region" {
  default = "us-east-1"
  type    = string
}

Use the optional ami_regions option to copy the AMI to additional regions. Tags and attributes are copied with it.

image_prefix — The prefix applied to the generated AMI name. Defaults to cnspec-tested-amazon-ubuntu-2404:

variable "image_prefix" {
  type        = string
  description = "Prefix to be applied to the image name"
  default     = "cnspec-tested-amazon-ubuntu-2404"
}

Initialize Packer

packer init aws-ubuntu2404.pkr.hcl

packer init downloads the plugins listed in required_plugins. Plugins are typically cached in ~/.packer.d/plugins. You can run packer init repeatedly; if the plugins are already present, Packer exits silently.

Build the AMI

packer build aws-ubuntu2404.pkr.hcl

Packer prints output similar to this (truncated for readability):

==> ...amazon-ebs.ubuntu2404: Prevalidating any provided VPC information
==> ...amazon-ebs.ubuntu2404: Prevalidating AMI Name: cnspec-tested-amazon-ubuntu-2404-...
==> ...amazon-ebs.ubuntu2404: Found Image ID: ami-XXXXXXXXXXXXXXXXX
==> ...amazon-ebs.ubuntu2404: Launching a source AWS instance...
==> ...amazon-ebs.ubuntu2404: Connected to SSH!
==> ...amazon-ebs.ubuntu2404: Running cnspec packer provisioner by Mondoo
==> ...amazon-ebs.ubuntu2404: scan packer build
...
==> Builds finished. The artifacts of successful builds are:
--> <image-name>.amazon-ebs.ubuntu2404: AMIs were created:
us-east-1: ami-XXXXXXXXXXXXXXXXX

View the scan report in Mondoo Platform (registered mode only)

The cnspec plugin sends scan results to Mondoo Platform. To view a build's report, open the Mondoo Console, navigate to INVENTORYASSETS, and select your asset.

Mondoo scan report from a HashiCorp Packer build

View the findings details

Select the Findings tab.

Findings tab in a Mondoo scan report from a HashiCorp Packer build

Select any finding to see documentation, audit context, and remediation steps:

Findings details in a Mondoo scan result

View the image in the AWS Management Console

Mondoo secure base image in AWS Management Console

After the build completes, open the AMIs page in the AWS Management Console.

Remove the image

Deregister the AMI from the AMIs page, then delete its associated snapshot from the Snapshots page.

Next steps

You built an Amazon AMI and scanned it for vulnerabilities and misconfigurations with cnspec.

The cnspec Packer plugin repository contains additional templates for other Linux distributions, Windows, and container builders.

On this page