Tutorials How to create custom templates with Packer

How to create custom templates with Packer

Packer is easy to use automation solution for creating any type of machine images. It embraces modern configuration management by allowing automated software install and setup within Packer-built images. Helping to create private templates faster, we are excited to introduce the UpCloud Packer builder.

UpCloud Packer builder works as a plugin for Packer to simplify template configuration and make deploying custom cloud servers faster. In this guide, you will find the required steps to installing Packer builder for UpCloud on your own computer running Linux. Each of the software used here is also available for macOS and Windows with their own installation instructions by their developers.

Test hosting on UpCloud!

Installing the prerequisites

Like with most installation instructions, the first step is to make sure you have the necessary tools to continue. In this case, you will need to have curl and unzip to follow along with the guide.

Verify that the aforementioned packages are installed with your system appropriate command such as one of the two examples below. If you wish to just go by the quickstart option, you can leave out the git tools.

sudo apt-get install curl unzip
sudo yum install curl unzip

Having the prerequisites fulfilled, you can get started with the installation.

Option 1. Quickstart

Packer is available packaged as a zip file. To install the precompiled binary, you will need to download the appropriate package for your OS. For example, using the following command to download the 64-bit Linux version of Packer.

curl -O https://releases.hashicorp.com/packer/1.7.0/packer_1.7.0_linux_amd64.zip

You might need to check the version number on the Packer website and update the URL.

When the download finishes, extract Packer into an appropriate directory that is included in your $PATH such as /usr/local/bin.

sudo unzip packer_1.7.0_linux_amd64.zip -d /usr/local/bin

Then verify that Packer is working, for example, with the command below.

packer --version

Installing Packer is all that you really need to build custom templates on UpCloud. Jump ahead to the last section in this tutorial to get started with building templates.

Alternatively, if you wish, you can manually download the pre-built binary of the plugin available on the GitHub releases page.

Download the archive appropriate for your operating system, for example on Linux with the command underneath.

curl -LO https://github.com/UpCloudLtd/packer-plugin-upcloud/releases/download/v1.0.0/packer-plugin-upcloud_v1.0.0_x5.0_linux_amd64.zip

Create a directory for the Packer plugins and unpack the binary into the new folder.

mkdir -p ~/.packer.d/plugins/github.com/upcloudltd/upcloud/
unzip packer-plugin-upcloud_v1.0.0_x5.0_linux_amd64.zip -d ~/.packer.d/plugins/github.com/upcloudltd/upcloud/packer-plugin-upcloud_v1.0.0_x5.0_linux_amd64

Then make sure the file is executable.

chmod +x ~/.packer.d/plugins/github.com/upcloudltd/upcloud/packer-plugin-upcloud_v1.0.0_x5.0_linux_amd64

With the plugin downloaded, continue in the last section to build your first template.

Option 2. Installing from the source

If you want to try out the latest version and build the binaries yourself, follow along with the instructions below. This part of the guide will show you how to install Go, Glide, Packer itself, and of course the UpCloud plugin for Packer.

Installing Go

Go is an open-source programming language that was developed to makes it easy to build simple, reliable, and efficient software. The Packer builder for UpCloud was written in Go while leveraging the UpCloud Go API.

Go binaries get frequent updates and the command below to download the install package might not be the latest. You can check for possible newer versions on their download page and change the version number in the package URL as necessary.

curl -O https://storage.googleapis.com/golang/go1.16.linux-amd64.tar.gz

Unpack the downloaded binaries to an appropriate location e.g. with the next command.

sudo tar -C /usr/local -xzf go1.16.linux-amd64.tar.gz

Then create a new directory to save any Go sources into. You are of course free to choose the location of the Go home directory. If you wish to store the related files somewhere else, set the GOPATH environmental variable accordingly.

mkdir -p ~/go/bin

Save the environmental variables in your profile with the following commands.

echo 'export GOPATH=$HOME/go' | tee -a ~/.profile
echo 'export GOBIN=$GOPATH/bin' | tee -a ~/.profile
echo 'export PATH=$PATH:/usr/local/go/bin:$GOBIN' | tee -a ~/.profile

Then reload the profile to apply the changes.

source ~/.profile

This way the paths are set correctly every time you log in or open a new terminal.

Installing Packer

Install Packer by downloading the latest release with the following command.

curl -O https://releases.hashicorp.com/packer/1.7.0/packer_1.7.0_linux_amd64.zip

You might need to check the version number on the Packer website and update the URL.

When the download finishes, extract Packer into an appropriate directory that is included in your $PATH such as /usr/local/bin.

sudo unzip packer_1.7.0_linux_amd64.zip -d /usr/local/bin

Then verify that Packer is working, for example, with the command below.

packer --version

With Packer itself installed and ready, continue below with installing the UpCloud plugin.

Installing packer-plugin-upcloud

Now, the last component needed to generate private templates on UpCloud is the Packer builder plugin.

Create a new directory to store your Packer configurations, for example, in your home folder.

mkdir ~/packer
cd ~/packer

Then download the plugin source from Github with the following command.

git clone https://github.com/UpCloudLtd/packer-plugin-upcloud

Next, change into the downloaded source directory.

cd ~/packer/packer-plugin-upcloud

You can then build the plugin using Go.

go build

Once compiled, the plugin can be found in the source directory but Packer doesn’t know how to use it from there. Instead, create a directory for the Packer plugins. Then copy the packer-plugin-upcloud binary there to make it available to Packer.

mkdir -p ~/.packer.d/plugins/github.com/upcloudltd/upcloud/
cp packer-plugin-upcloud ~/.packer.d/plugins/github.com/upcloudltd/upcloud/packer-plugin-upcloud_v1.0.0_x5.0_linux_amd64

That is it for the installation. You should now be able to generate templates on UpCloud using Packer commands. Continue below to test it out.

Building a template with Packer

Packer uses the hcl format for configuration files to define the template you wish to build. If you installed the plugin from the source, you can locate an example configuration file in the sources directory under .../packer-plugin-upcloud/examples. Copy the example file to somewhere convenient, e.g. in ~/packer.

cp ~/packer/packer-plugin-upcloud/examples/basic_example.pkr.hcl ~/packer/

Then open the template with your favourite editor, for example using the following command.

nano ~/packer/basic_example.pkr.hcl

If you just downloaded the prebuilt binaries, you can find the example in the repository. Alternatively, just copy and paste the same template found below. Create a template file basic_example.pkr.hcl where ever convenient.

The basic template is ready to deploy, but you should take a look at the parameters in the builders segment. The type, username, and password are rather self-explanatory and should be the same for every template. The important parts are the target zone and the original storage-name. These tell Packer which public template you wish to use as the basis for generating your own and where it should be made available.

Choose the zone where you wish to deploy cloud servers with the custom template. The currently available zones are the following:

  • Helsinki fi-hel1
  • Helsinki fi-hel2
  • London uk-lon1
  • Frankfurt de-fra1
  • Chicago us-chi1
  • New York us-nyc1
  • San Jose us-sjo1
  • Amsterdam nl-ams1
  • Singapore sg-sin1
  • Madrid es-mad1
  • Warsaw pl-waw1

The second bit you should select is the public template that will be used to generate your custom template. The example configuration below uses the Ubuntu 20.04 image, but you can use any Linux template you wish available as a public template on UpCloud.

With the basic configuration done, the customization to the template can then be added to the provisioners segment. The example provisioner runs the basic update and upgrade commands in the shell.

Additionally, if you want to log into a server deployed with the template, you might want to include an SSH key to your root user by replacing the <ssh-rsa_key> with your public key or provision another username. The Packer generates a temporary SSH key while building the template which cannot be used afterwards.

You can find instructions on how to use different types of provisioners to customize your template at the Packer documentation for provisioners.

variable "username" {
  type = string
  default = "${env("UPCLOUD_API_USER")}"

variable "password" {
  type = string
  default = "${env("UPCLOUD_API_PASSWORD")}"

packer {
    required_plugins {
        upcloud = {
            version = ">=v1.0.0"
            source = "github.com/UpCloudLtd/upcloud"

source "upcloud" "test" {
  username = "${var.username}"
  password = "${var.password}"
  zone = "nl-ams1"
  storage_name = "ubuntu server 20.04"
  template_prefix = "ubuntu-server"

build {
  sources = ["source.upcloud.test"]

  provisioner "shell" {
    inline = [
      "apt-get update",
      "apt-get upgrade -y",
      "echo '<ssh-rsa key>' | tee /root/.ssh/authorized_keys"

Once you have made the configurations, save the file and exit the editor.

The Packer builder leverages the UpCloud Go API to interface with the UpCloud API. You will need to provide a username and password with the access rights to the API functions to authenticate. We recommend setting up a workspace member account with only the API privileges for security purposes. You can do this at your UpCloud Control Panel. Learn more about creating API credentials at our guide for getting started with UpCloud API.

Enter the API user credentials in your terminal with the following two commands. Replace the <API_username> and <API_password> with your user details.

export UPCLOUD_API_USER=<API_username>
export UPCLOUD_API_PASSWORD=<API_password>

You should save these in your profile file to avoid having to repeat the command every time you open a new terminal. Simply add the same lines to the ~/.profile or ~/.bashrc file.

Now that you have a template configuration and credentials ready, initialise Packer with the following command.

packer init ~/packer/basic_example.pkr.hcl

This will tell Packer to prepare to build the template and check for the required plugin. If you use the quick start method, Packer will download the UpCloud Packer builder and save it in ~/.packer.d/plugins directory. You should see a confirmation such as in the example output below.

Installed plugin github.com/upcloudltd/upcloud v1.0.0 in "/home/user/.packer.d/plugins/github.com/upcloudltd/upcloud/packer-plugin-upcloud_v1.0.0_x5.0_linux_amd64"

You are then ready to build your template. Use the command below to generate a template based on the configuration file.

packer build ~/packer/basic_example.pkr.hcl
==> upcloud: Creating temporary SSH key ...
==> upcloud: Getting storage...
==> upcloud.test: Creating server based on storage "Ubuntu Server 20.04 LTS (Focal Fossa)"... 
==> Wait completed after 3 minutes 49 seconds

==> Builds finished. The artifacts of successful builds are:
--> upcloud.test: Storage template created, UUID: 01f13bb4-ca38-4d7f-baa0-2bb14a18631d

When the deployment process finishes, you should see output similar to the example above.


Congratulations, you should now have your own custom template visible at your UpCloud Control Panel under Storage and Custom images tab. With the simple configuration process and the fast deployment, you can have a purpose build template ready in minutes.

Test it out by pressing the Deploy button and start a new server from the custom template to verify it was build to your specifications.

Editor-in-chief and Technical writer at UpCloud since 2015. Cloud enthusiast writing about server technology and software.

Leave a Reply

Your email address will not be published. Required fields are marked *


Helsinki (HQ)

In the capital city of Finland, you will find our headquarters, and our first data centre. This is where we handle most of our development and innovation.


London was our second office to open, and a important step in introducing UpCloud to the world. Here our amazing staff can help you with both sales and support, in addition to host tons of interesting meetups.


Singapore was our 3rd office to be opened, and enjoys one of most engaged and fastest growing user bases we have ever seen.


Seattle is our 4th and latest office to be opened, and our way to reach out across the pond to our many users in the Americas.