Creating Snapshots With Packer

Updated on November 21, 2023
Creating Snapshots With Packer header image

Introduction

Packer is a server imaging tool developed by HashiCorp. Server imaging, or immutable infrastructure, is a popular alternative to runtime configuration tools, such as Ansible or Puppet. It is based on the idea that once a server is deployed, you never change it; instead, you deploy a new server with your changes and then tear down the old one. This makes server maintenance easier and allows you to scale across a large number of machines more efficiently.

Packer supports Vultr via a Packer Builder plugin. This article explains how to install Packer, the Vultr plugin, and build a simple snapshot.

Packer produces server images, also called artifacts, that can recreate a server exactly as it was imaged. Vultr calls these artifacts snapshots. For example, the Vultr Packer Builder plugin deploys a new VPS, runs your defined provisioners on it, creates a snapshot, then destroys the VPS. You can deploy the snapshot from the web portal or via the Vultr API to create a new server.

Prerequisites

This guide uses a temporary VPS as a build workstation, so you can follow this guide without installing anything on your personal workstation. To get started:

  1. Deploy an Ubuntu 20.04 LTS server instance at Vultr.
  2. Follow our best practices guide to update the server.

The rest of this guild refers to this server as the Build Workstation.

1. Create a Packer HCL file

Packer reads an HCL format file that defines the snapshot. For this guide, you'll create a simple HCL file that defines a CentOS 7 snapshot.

  1. SSH to the build workstation as root.

  2. Create a new centos7.pkr.hcl file in your editor.

     # nano ~/centos7.pkr.hcl

    Paste the following into the editor. You'll learn more about these values later in this guide.

     variable "vultr_api_key" {
       type      = string
       default   = "${env("VULTR_API_KEY")}"
       sensitive = true
     }
    
     packer {
       required_plugins {
         vultr = {
           version = ">=v2.3.2"
           source = "github.com/vultr/vultr"
         }
       }
     }
    
     source "vultr" "centos7" {
       api_key              = "${var.vultr_api_key}"
       os_id                = "167"
       plan_id              = "vc2-1c-1gb"
       region_id            = "ewr"
       snapshot_description = "CentOS 7 ${formatdate("YYYY-MM-DD hh:mm", timestamp())}"
       ssh_username         = "root"
       state_timeout        = "25m"
     }
    
     build {
       sources = ["source.vultr.centos7"]
    
       provisioner "shell" {
         script = "centos7.sh"
       }
     }
  3. Save and exit the file.

2. Create a Provisioning Script

The Packer HCL file calls a shell provisioning script named centos7.sh during the build process. Follow these steps to create a simple provisioning script.

  1. Create a new centos7.sh file in your editor.

     # nano ~/centos7.sh

    Paste the following into the editor. This simple provisioning script updates the server's packages and wipes empty disk space before Packer creates the snapshot.

     #!/bin/bash
     #############################################
     ## Build example CentOS 7 snapshot at Vultr
     #############################################
    
     ## Update the server.
     yum update -y
    
     ## Wipe unused disk space with zeros for security and compression.
     echo "Clearing free disk space. This may take several minutes."
     dd if=/dev/zero of=/zerofile status=progress
     sync
     rm /zerofile
     sync
     echo "System setup is complete. Begin snapshot process."
  2. Save and exit the file.

3. Install Hashicorp Packer

Install Packer on the Ubuntu Build Workstation.

  1. Add the HashiCorp GPG key.

     # curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
  2. Add the official HashiCorp Linux repository.

     # sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
  3. Update and install.

     # sudo apt-get update && sudo apt-get install packer

If you used a different OS for your build workstation, follow the appropriate installation instructions.

4. Install the Vultr Packer Builder

Starting with Packer version 1.7.0, plugins are installed with the packer init command, which examines the HCL file to determine what plugin to install. The HCL file you created earlier has this required_plugins section:

packer {
  required_plugins {
    vultr = {
      version = ">=v2.3.2"
      source = "github.com/vultr/vultr"
    }
  }
}

To install the Vultr Packer Builder plugin, run:

# packer init ~/centos7.pkr.hcl

Packer downloads the plugin from GitHub and installs it.

5. Create a Snapshot with Packer

To create the server snapshot, run:

# packer build ~/centos7.pkr.hcl

More about the HCL File

Here are more details about the different sections in the centos7.pkr.hcl file.

The variable Section

This section defines a local Packer variable, vultr_api_key, which is populated with the value of the shell environment variable $VULTR_API_KEY. The local variable is marked sensitive so it won't be displayed or written to log files.

variable "vultr_api_key" {
  type      = string
  default   = "${env("VULTR_API_KEY")}"
  sensitive = true
}

The packer Section

This section defines the required plugins. In this case, Vultr plugin version 2.3.2 or greater.

packer {
  required_plugins {
    vultr = {
      version = ">=v2.3.2"
      source = "github.com/vultr/vultr"
    }
  }
}

The source Section

This section defines a vultr.centos7 source and passes several bits of information to it:

source "vultr" "centos7" {
  api_key              = "${var.vultr_api_key}"
  os_id                = "167"
  plan_id              = "vc2-1c-1gb"
  region_id            = "ewr"
  snapshot_description = "CentOS 7 ${formatdate("YYYY-MM-DD hh:mm", timestamp())}"
  ssh_username         = "root"
  state_timeout        = "25m"
}
  • api_key: The Vultr API key.
  • os_id: 167 is the code for CentOS 7. See all available OS IDs with the Vultr API.
  • plan_id: vc2-1c-1gb is a Vultr Cloud Compute plan with 1 vCPU and 1 GB RAM. See all available plans with the Vultr API.
  • region_id: ewr is the New Jersey location. See the region list with the Vultr API.
  • snapshot_description: A friendly description for the snapshot, shown in the customer portal. In this case, the name is "CentOS 7" followed by the date and time the snapshot was created.
  • ssh_username: The user that runs the provisioning script.
  • state_timeout: Wait up to 25 minutes for a snapshot to complete.

The build Section

The build section is where all the information comes together.

build {
  sources = ["source.vultr.centos7"]

  provisioner "shell" {
    script = "centos7.sh"
  }
}

In this example, Packer:

  • Builds a server described by the vultr.centos7 source section
  • Runs the provisioning script centos7.sh
  • Makes a snapshot
  • Destroys the server

Once the build is finished, Packer will output the ID of the resulting snapshot, which remains as the build artifact. You can use the snapshot to launch as many identical servers as needed.

More Information

For more information, please see Packer's documentation.