Skip to main content

Building secure AMIs with Mondoo and Packer

This tutorial covers how run Mondoo security scans during HashiCorp Packer builds of Amazon EC2 AMIs.

caution

This tutorial will provision resources that qualify under the AWS Free Tier. If your account doesn't qualify under the AWS Free Tier, Mondoo is not responsible for any charges that you may incur.

Prerequisites

Before you begin, make sure you've performed these tasks:

Packer Plugin Mondoo

The Packer Plugin Mondoo makes it easy to integrate Mondoo security scanning with HashiCorp Packer builds. This integration lets you find and fix vulnerabilities and misconfigurations before provisioning them in your environment.

The plugin calls Mondoo Client after running packer build and authenticates with Mondoo Platform to run any policies enabled in the account Mondoo Client is registered to.

Enable security policies

For the purposes of this guide, enable the Platform Vulnerability Policy by Mondoo, which works with both Linux and Windows.

To enable security policies:

  1. Log in to Mondoo Platform.
  2. Navigate to the POLICY HUB.
  3. Select the ADD POLICY to view the all available policies.
  4. Search for Platform Vulnerability Policy by Mondoo using the Filter search box.
  5. Check the box next to the policy and then select the ENABLE button.

If you need to customize the controls in a policy, see Customizing Policies.

Configure Mondoo Client

Before running Packer, validate Mondoo Client is configured to the correct account and space in Mondoo Platform:

➜  ~ mondoo status
...
→ client is registered
→ client authenticated successfully

Write the Packer template

A Packer template is a configuration file that defines the image you want to build and how to build it. Packer templates use the HashiCorp Configuration Language (HCL).

Create a new directory named mondoo_packer. This directory will contain your Packer template for this tutorial.

$ mkdir mondoo_packer

Navigate into the directory.

$ cd mondoo_packer

Create a file aws-amazon2.pkr.hcl, add the following HCL block to it, and save the file.

packer {
required_plugins {
amazon = {
version = ">= 1.1.0"
source = "github.com/hashicorp/amazon"
}
mondoo = {
version = ">= 0.3.0"
source = "github.com/mondoohq/mondoo"
}
}
}

variable "aws_profile" {
type = string
description = "AWS profile to use. Typically found in ~/.aws/credentials"
default = "default"
}

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

variable "image_prefix" {
type = string
description = "Prefix to be applied to image name"
default = "mondoo-amazon-linux-2-secure-base"
}

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

source "amazon-ebs" "amazon2" {
profile = var.aws_profile
ami_name = "${var.image_prefix}-${local.timestamp}"
instance_type = "t2.micro"
region = var.aws_region
source_ami_filter {
filters = {
name = "amzn2-ami-kernel-5.*-x86_64-gp2"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["137112412989"]
}
ssh_username = "ec2-user"
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.amazon2"
]

provisioner "shell" {
inline = [
"sudo hostnamectl set-hostname ${var.image_prefix}-${local.timestamp}",
"sudo yum update -y",
"sudo yum upgrade -y"]
}

provisioner "mondoo" {
score_threshold = 80
on_failure = "continue"
asset_name = "${var.image_prefix}-${local.timestamp}"

annotations = {
Source_AMI = "{{ .SourceAMI }}"
Creation_Date = "{{ .SourceAMICreationDate }}"
}
}
}

This is a complete Packer template that you will use to build an AWS Amazon 2 Linux AMI in the us-east-1 region. In the following sections, you will review each block of this template in more detail.

Configure the template

The template provides a few variables that can be configured to the template before building an AMI. For more information on how to override Packer template variables see Template User Variables in the Packer documentation.

Authenticate with AWS

Before you can build the AMI, you need to provide your AWS credentials to Packer.

The template above has an aws_profile variable that lets you configure a profile from your AWS CLI credentials file, which is usually found in ~/.aws/credentials.

variable "aws_profile" {
type = string
description = "AWS profile to use. Typically found in ~/.aws/credentials"
default = "default"
}

These credentials have permissions to create, modify and delete EC2 instances. Refer to the Packer documentation to find the full list IAM permissions required to run the amazon-ebs builder.

tip

If you don't have access to IAM user credentials, use another authentication method described in the Amazon AMI Builder documentation.

AWS region

By default the template will create the AMI in the us-east-1 region of AWS. You can override this with the aws_region variable:

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

Image prefix

By default the template will create the AMI using a default naming prefix of mondoo-amazon-linux-2-secure-base. You can override this with the image_prefix variable:

variable "image_prefix" {
type = string
description = "Prefix to be applied to image name"
default = "mondoo-amazon-linux-2-secure-base"
}

Configure Packer Plugin Mondoo

Packer Plugin Mondoo provides a number of configurations that you can change to meet your needs.

provisioner "mondoo" {
score_threshold = 80
on_failure = "continue"
asset_name = "${var.image_prefix}-${local.timestamp}"

annotations = {
Source_AMI = "{{ .SourceAMI }}"
Creation_Date = "{{ .SourceAMICreationDate }}"
}
}
  • score_threshold - This configuration sets an int score threshold for security scans. If the scan produces a score that falls below the threshold, the build will fail. If your build runs multiple Mondoo policies, then it is the aggregated score that is evaluated. For more information see Policy Scoring in the Mondoo documentation.
  • on_failure = "continue" - This configuration ensures that the Packer build will not fail even if the scan produces a score that falls below the score_threshold. Mondoo will send the scan report to your account in Mondoo Platform for your reference, and the build will complete.
  • annotations - This configuration lets you create custom metadata for builds so that you can track your assets.

Initialize the Packer configuration

Initialize your Packer configuration.

➜  mondoo_packer packer init aws-amazon2.pkr.hcl
Installed plugin github.com/hashicorp/amazon v1.1.0 in "/Users/youruser/.packer.d/plugins/hashicorp/amazon/packer-plugin-amazon_v1.1.0_x5.0_darwin_arm64"
Installed plugin github.com/mondoohq/mondoo v0.3.0 in "/Users/youruser/.packer.d/plugins/mondoohq/mondoo/packer-plugin-mondoo_v0.3.0_x5.0_darwin_arm64"

Packer will download the plugin you've defined above. In this case, Packer will download the Packer Amazon plugin that is greater than version 1.1.0 and Packer Plugin Mondoo greater than version 0.3.0.

You can run packer init as many times as you'd like. If you already have the plugins you need, Packer will exit without an output.

Packer has now downloaded and installed the Amazon plugin and the Mondoo plugin. It is ready to build the AMI!

Build the Packer image

Build the image with the packer build <template> command. Packer will print output similar to what is shown below.

➜  mondoo_packer packer build aws-amazon2.pkr.hcl
<image-name>: output will be in this color.

==> <image-name>: Prevalidating any provided VPC information
==> <image-name>: Prevalidating AMI Name: mondoo-amazon-linux-2-secure-base-20220620035706
<image-name>: Found Image ID: ami-0cff7528ff583bf9a
==> <image-name>: Creating temporary keypair: packer_62aff012-2058-915b-d8c5-8f9de8280c2f
==> <image-name>: Creating temporary security group for this instance: packer_62aff015-1704-09d1-e67b-5607839fc942
==> <image-name>: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> <image-name>: Launching a source AWS instance...
<image-name>: Instance ID: i-09fd19500953db58b
==> <image-name>: Waiting for instance (i-09fd19500953db58b) to become ready...
...
==> <image-name>: Running Mondoo packer provisioner (Version: 0.3.0, Build: db076f5)
==> <image-name>: Executing Mondoo: [mondoo scan ssh ec2-user@52.3.73.121:22 --score-threshold 0]
<image-name>: → Mondoo 6.2.0 (Space: "//captain.api.mondoo.app/spaces/pedantic-yalow-561178", Service Account: "29MBsedVF1I0wF3qiBnKgFYMFRV", Managed Client: "unset")
<image-name>: → loaded configuration from /Users/scottford/.config/mondoo/packer-builder.yml using source $MONDOO_CONFIG_PATH
<image-name>: → discover related assets for 1 asset(s)
<image-name>: → resolved assets resolved-assets=1
<image-name>: → establish connection to asset mondoo-amazon-linux-2-secure-base-20220620035706 (unknown)
<image-name>: → run policies for asset asset=mondoo-amazon-linux-2-secure-base-20220620035706
...
<image-name>: Vulnerabilities:
<image-name>: ■ No advisories found (passed)
<image-name>:
<image-name>: Overall CVSS score: 0.0
<image-name>:
<image-name>:
<image-name>: Summary
<image-name>: ========================
<image-name>:
<image-name>: Target: mondoo-amazon-linux-2-secure-base-20220620035706
<image-name>: Score: A 100/100 (100% completed)
<image-name>: ✓ Passed: ███████████████ 100% (3)
<image-name>: ✕ Failed: 0% (0)
<image-name>: ! Errors: 0% (0)
<image-name>: » Skipped: 0% (0)
<image-name>:
<image-name>: Policies:
<image-name>: A 100 Platform Vulnerability Policy by Mondoo
<image-name>:
<image-name>: Report URL: https://console.mondoo.com/space/fleet/2ApDCddQBoUXjHR7g4sAAAAAA?spaceId=abc123
==> <image-name>: Stopping the source instance...
<image-name>: Stopping instance
==> <image-name>: Waiting for the instance to stop...
==> <image-name>: Creating AMI mondoo-amazon-linux-2-secure-base-20220620035706 from instance i-09fd19500953db58b
<image-name>: AMI: ami-00e59a4c840f537ad
==> <image-name>: Waiting for AMI to become ready...
Build '<image-name>' finished after 8 minutes 9 seconds.

==> Wait completed after 8 minutes 9 seconds

==> Builds finished. The artifacts of successful builds are:
--> <image-name>: AMIs were created:
us-east-1: ami-00e59a4c840f537ad

View the scan results in STDOUT

During the build process you will see scan results similar to this:

<image-name>: Vulnerabilities:
<image-name>: ■ No advisories found (passed)
<image-name>:
<image-name>: Overall CVSS score: 0.0
<image-name>:
<image-name>:
<image-name>: Summary
<image-name>: ========================
<image-name>:
<image-name>: Target: mondoo-amazon-linux-2-secure-base-20220620035706
<image-name>: Score: A 100/100 (100% completed)
<image-name>: ✓ Passed: ███████████████ 100% (3)
<image-name>: ✕ Failed: 0% (0)
<image-name>: ! Errors: 0% (0)
<image-name>: » Skipped: 0% (0)
<image-name>:
<image-name>: Policies:
<image-name>: A 100 Platform Vulnerability Policy by Mondoo
<image-name>:
<image-name>: Report URL: https://console.mondoo.com/space/fleet/2ApDCddQBoUXjHR7g4sAAAAAA?spaceId=abc123

View the report in Mondoo Platform

Packer Plugin Mondoo also sends the scan results to your account in Mondoo Platform.

Mondoo scan report from HashiCorp Packer build

View the control details

You can expand each control in a policy to show additional documentation, audit, and remediation steps:

Mondoo Platform vulnerability policy - control details

View the image AWS Management Console

Mondoo secure base image in AWS Management Console

After running the above example, you can navigate to the AMIs section of AWS Management Console.

Remove the image

You can remove the AMI by first deregistering it on the AWS AMI management page. Next, delete the associated snapshot on the AWS snapshot management page.

Next steps

In this tutorial, you built an Amazon AMI and scanned it for vulnerabilities with Mondoo. Although we ran the one policy, you should now have a general idea of how Packer Plugin Mondoo works, and you should be ready to add any additional policies for your builds.

The GitHub repository for Packer Plugin Mondoo contains additional templates for building Ubuntu and Windows images.

Refer to the following resources for additional details on the concepts covered in this tutorial: