Create and manage images with Packer

Modified: 22 May 2023 20:10 UTC

There are a number of ways to deploy custom applications on Triton. Triton provides multiple hardware virtual machine (HVM) and infrastructure images to meet your various application needs. Run triton images to see a list of what's available.

Packer is platform-agnostic. That means if you've got existing Packer templates which build images for other cloud providers, it's easy to adapt them to build those same images on Triton.

Although those images can be deployed into containers that can be customized individually, that extra work can be cumbersome and difficult to replicate.

Installing Packer

Before you can create an image with Packer, you must install it.

It is also important to set the PATH for your system.

Set PATH for macOS or Linux

Edit your bash profile (that may look like .bash_profile or .bashrc) to add the PATH and other environment variables, just as you've done for CloudAPI environment variables.

Add the following content:

export PATH=$PATH:/usr/local/packer

If you've installed Packer in a different directory, you must modify /usr/local/packer to reflect the correct information.

Set PATH for Windows

You can set the PATH by going to the Control Panel -> System -> Advanced System Settings. Under Environment Variables, scroll until you find PATH. Edit accordingly and be sure to include a semicolon at the end of any previously set paths. For example:

c:\path\to\example1;c:\path\to\packer

Validate Packer's installation

Validate the installation of Packer by running packer in your terminal:

$ packer
Usage: packer [--version] [--help] <command> [<args>]

Available commands are:
    build       build image(s) from template
    fix         fixes templates from old versions of packer
    inspect     see components of a template
    push        push a template and supporting files to a Packer build service
    validate    check that a template is valid
    version     Prints the Packer version

If packer cannot be found, PATH was not properly set up.

Create a Packer template

To create a Packer image for an application, you must create a Packer template. The template can live either within a local directory of the application or in a separate empty directory.

The configuration file determines the type of image being built and is written in JSON. For example, this file may be called my-application.json.

Add variables

The contents of the file begin with Triton environment variables for your account, followed by the builders and provisioners.

NOTE: Though it is possible to create a Packer configuration file without setting up environment variables, we do not advise you do so. It is a best practice to store all important keys locally as environment variables instead of tying it to your application files.

Variables are particularly useful when it comes to sensitive information, such as your account login and SSH key fingerprint. These are the same variables used for CloudAPI and other Triton tools. To access these variables, it's important to set the Triton environment before building your image.

{
  "variables": {
      "triton_url": "{{env `SDC_URL`}}",
      "triton_account": "{{env `SDC_ACCOUNT`}}",
      "triton_key_id": "{{env `SDC_KEY_ID`}}"
  },

Add Packer builders

Builders create machine images for individual platforms. Triton is a builder, using CloudAPI to create the image. The builder launches a temporary VM based on the template, runs any provisioning necessary, creates a reusable image, and then destroys the VM. This builder does not manage images; you must use or delete it with CloudAPI outside of Packer.

Below is an example of a Triton builder for a web-based application using Nginx.

"builders": [
   {
      "type": "triton",
      "triton_url": "{{user `triton_url`}}",
      "triton_account": "{{user `triton_account`}}",
      "triton_key_id": "{{user `triton_key_id`}}",

      "source_machine_image_filter": {
         "name": "nginx",
         "most_recent": "true"
      },
      "source_machine_package": "g4-highcpu-128M",

      "ssh_username": "root",

      "image_name": "my_application",
      "image_version": "1.0.0",
      "image_tags": {
         "Project": "My Application"
      }
   }
],

NOTE: For your SSH key to be usable, it must be available through the ssh-agent.

There is also a Docker builder available to create custom Docker images.

Add provisioners to customize the image

Provisioners install and configure software within a running machine prior to the machine becoming a static image. The provisioners perform the work that customizes Triton images to contain software including installing packages, creating users, and downloading application code.

Two of the most common provisioners are file and shell.

The file provisioner uploads files to machines built by Packer. The recommended usage of the file provisioner is to use it to upload files, and then use shell provisioner to move them to the proper place, set permissions, etc. The file provisioner can refer to a single file, such as index.html, or an entire directory, such as directory/.

"provisioners": [
   {
      "type": "file",
      "source": "index.html",
      "destination": "/usr/share/nginx/html/"
   },   {
      "type": "file",
      "source": "directory-name/",
      "destination": "/usr/share/nginx/html/directory-name/"
   }
]
}

The shell provisioner provisions machines built by Packer using shell scripts. Shell provisioning is the easiest way to get software installed and configured on a machine.

"provisioners": [
   {
      "type": "shell",
      "script": "create-directories.sh"
   }
]
}

Read more about provisioners.

Build a Packer image

Once your template is complete, you can proceed to build the application image.

Validate the Packer template and ensure that the JSON syntax and configuration values are correct.

$ packer validate my-application.json
Template validated successfully.

NOTE: If the template validation was not successful, that means there is an error in your configuration file. The validate command should tell you where to find the error.

to create the image

To create your Packer image, execute packer build with the name of the template file. The output will look something like this:

$ packer build my-application.json
triton output will be in this color.

==> triton: Waiting for source machine to become available...
==> triton: Waiting for SSH to become available...
==> triton: Connected to SSH!
==> triton: Provisioning with shell script: add-directories.sh
==> triton: Uploading index.html => /usr/share/nginx/html/
==> triton: Uploading css/ => /usr/share/nginx/html/css/
==> triton: Uploading js/ => /usr/share/nginx/html/js/
==> triton: Stopping source machine (6163c9e1-0ee6-eccb-c8bb-9f4369c73bb0)...
==> triton: Waiting for source machine to stop (6163c9e1-0ee6-eccb-c8bb-9f4369c73bb0)...
==> triton: Creating image from source machine...
==> triton: Waiting for image to become available...
==> triton: Deleting source machine...
==> triton: Waiting for source machine to be deleted...
Build 'triton' finished.

==> Builds finished. The artifacts of successful builds are:
--> triton: Image was created: c7da3619-5b1d-4fc7-bde6-503a3f8450b1

Artifacts are the result of a single build, including a set of IDs or files that represent the final machine image. Every builder produces a single artifact. For the Triton builder, the artifact is the new image ID.

View custom Packer images with Triton CLI

To see the custom Packer image details with Triton CLI, use triton image get with either the image ID or the image name.

$ triton image get my_application

Next steps

Once the image is created, you can create an instance. Read our documentation on instance creation.