Run Goss Tests During a Packer Build

Easily run goss tests on an image during a packer build, now available during provisioning. Find an example packer build with goss tests in the example/ directory of the Github repository.

To use Goss Packer Provisioner with an Ubuntu 20.04 AMI, follow these steps:

  1. Install prerequisites:

    a. Install Packer: Download and install Packer from https://www.packer.io/downloads.html, following the appropriate instructions for your operating system.

    b. Install Goss: Download and install Goss from https://github.com/aelsabbahy/goss/releases. Ensure the binary is in your system’s PATH.

    c. Install Goss Packer Provisioner: Download the plugin from https://github.com/YaleUniversity/packer-provisioner-goss/releases and place the binary in your Packer plugins directory (~/.packer.d/plugins on Unix systems or %APPDATA%\packer.d\plugins on Windows).

  2. Create a Packer configuration file (e.g., ubuntu-20.04-ami.json):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
  "variables": {
    "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
    "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "access_key": "{{user `aws_access_key`}}",
      "secret_key": "{{user `aws_secret_key`}}",
      "region": "us-west-2",
      "source_ami_filter": {
        "filters": {
          "virtualization-type": "hvm",
          "name": "ubuntu/images/*ubuntu-focal-20.04-amd64-server-*",
          "root-device-type": "ebs"
        },
        "owners": ["099720109477"],
        "most_recent": true
      },
      "instance_type": "t2.micro",
      "ssh_username": "ubuntu",
      "ami_name": "ubuntu-20.04-ami-{{timestamp}}"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "inline": [
        "sudo apt-get update",
        "sudo apt-get install -y nginx"
      ]
    },
    {
      "type": "goss",
      "url": "https://github.com/aelsabbahy/goss/releases/download/v0.3.16/goss-linux-amd64",
      "goss_file": "goss-ubuntu-20.04.yaml"
    }
  ]
}

The goss section of the provisioners block is a JSON object represents a Goss provisioner configuration for a Packer build. The provisioner is responsible for running validation tests using the Goss tool during the image building process. The JSON object contains the following fields:

  • "type": "goss": Specifies that this provisioner is of type “goss”.
  • "url": "https://github.com/aelsabbahy/goss/releases/download/v0.3.16/goss-linux-amd64": Provides the URL to download the Goss binary. In this case, it points to the version 0.3.16 Linux binary of Goss.
  • "goss_file": "goss-ubuntu-20.04.yaml": Specifies the Goss test file that contains the validation tests to be run during the provisioning process. The test file, “goss-ubuntu-20.04.yaml”, should include a set of tests written in YAML format.

This configuration will cause Packer to download the specified Goss binary and run the tests from the “goss-ubuntu-20.04.yaml” file during the image building process.

  1. Create a Goss test file (e.g., goss-ubuntu-20.04.yaml):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package:
  nginx:
    installed: true
    versions:
      - "1.18.0-*"

service:
  nginx:
    enabled: true
    running: true

port:
  tcp:80:
    listening: true
    ip:
      - 0.0.0.0
  1. Set your AWS credentials as environment variables:
1
2
export AWS_ACCESS_KEY_ID=your_aws_access_key
export AWS_SECRET_ACCESS_KEY=your_aws_secret_key
  1. Run Packer to build the AMI:
1
packer build ubuntu-20.04-ami.json

Packer will now create an Ubuntu 20.04 AMI, install NGINX, and validate the instance using the Goss tests specified in goss-ubuntu-20.04.yaml.

Provisioners Block

1
2
3
4
5
6
7
8
"provisioners" : [
  {
    "type": "goss",
    "tests": [
      "goss/goss.yaml"
    ]
  }
]

The “provisioners” block in this JSON configuration defines a list of actions to be performed on the image during the Packer build process. In this case, there is only one provisioner, which is of type “goss”. This provisioner uses the Goss tool to run validation tests against the image being built.

The “tests” field within the “goss” provisioner specifies an array of Goss test files to be executed. In this example, only one test file, “goss/goss.yaml”, is provided. This test file contains a set of tests written in YAML format that Goss will use to validate the image’s configuration, ensuring that it meets the desired state.

  1. First configuration:
1
2
3
4
5
6
7
8
"provisioners": [
  {
    "type": "goss",
    "tests": [
      "goss/goss.yaml"
    ]
  }
]
  1. Second configuration:
1
2
3
4
5
{
  "type": "goss",
  "url": "https://github.com/aelsabbahy/goss/releases/download/v0.3.16/goss-linux-amd64",
  "goss_file": "goss-ubuntu-20.04.yaml"
}

Both configurations represent the Goss provisioner within the Packer build process. However, there are some differences between the two:

  1. In the first configuration, the Goss provisioner is defined within the provisioners array. In the second configuration, the Goss provisioner object is shown in isolation, without the surrounding provisioners array. Typically, this object would also be placed inside a provisioners array in the Packer configuration file.

  2. The first configuration uses the "tests" field, which is an array containing a single test file, “goss/goss.yaml”. The second configuration uses the "goss_file" field, specifying “goss-ubuntu-20.04.yaml” as the test file.

  3. The second configuration includes a "url" field, which provides the download URL for the Goss binary. This field is not present in the first configuration, which means Packer will use the Goss binary installed on the system, or attempt to download it automatically if not found.

In summary, both configurations are for the Goss provisioner, but the second one includes a specific Goss binary URL and uses a different field to specify the test file. The first configuration is a part of the provisioners array, while the second one is shown in isolation.

Both configurations are valid, but they have slightly different implications. They both represent a Goss provisioner within a Packer build process but with some differences:

  1. The first configuration assumes the Goss binary is already installed on your system or that Packer will download it automatically. The second configuration provides a specific URL to download the Goss binary. If you want to use a specific Goss version or ensure the binary is downloaded during the build process, use the second configuration.

  2. The first configuration specifies the test file using the "tests" field, which can include multiple test files in the array. The second configuration uses the "goss_file" field to specify a single test file.

If you want to use either of these configurations in your Packer file, make sure to place the Goss provisioner object inside the provisioners array, like this:

1
2
3
4
5
6
7
8
"provisioners": [
  {
    "type": "goss",
    "tests": [
      "goss/goss.yaml"
    ]
  }
]

or

1
2
3
4
5
6
7
"provisioners": [
  {
    "type": "goss",
    "url": "https://github.com/aelsabbahy/goss/releases/download/v0.3.16/goss-linux-amd64",
    "goss_file": "goss-ubuntu-20.04.yaml"
  }
]

Choose the configuration that best suits your needs and use it in your Packer build process.