Deploy Cloud Instances with Packer and Terraform


Packer is a tool for creating identical machine images for multiple platforms from a single source configuration file. It can build images for multiple cloud hosting platforms, including Scaleway.

Terraform is an open source tool for building, changing, and versioning infrastructure safely and efficiently.

Both applications are available for Linux, MacOS, Windows, FreeBSD and NetBSD.

Downloading and Installing Packer

1 . Download Packer for your Operating system. If you want to have some specific configuration, you can also build the application from source.

Note: There is currently a bug with the Packer Builder for Scaleway and Packer 1.3.1. Build may fail when using this version. You may use an earlier Version of Packer as a temporary bug fix.

2 . Install the application on your computer

3 . Verify that the application is working properly, by opening a terminal and typing packer --help. You will see an output like the following:

$ packer --help
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

Packer Configuration Files

Packer builds images by taking a base image and installing additional software on it.

To use Packer with Scaleway, you must generate an API-Token from the management console.

Packer uses JSON files for the configuration.

The following are the required configuration parameters for a minimal configuration file:

  • organization_id (string) - The organization id to use to identify your organization. It can also be specified via environment variable SCALEWAY_ORGANIZATION.

  • api_token (string) - The token to use to authenticate with your account.

  • image (string) - The UUID of the base image to use. This will be used to boot the server on, before launching the additional tasks. A complete list of all base image UUIDs is available at

  • region (string) - The name of the region to launch the server and where the snapshot will be available.

  • commercial_type (string) - The name of the commercial type used to boot: ARM64-128GB,ARM64-16GB,ARM64-2GB,ARM64-32GB,ARM64-4GB, ARM64-64GB, ARM64-8GB,C1,C2L,C2M,C2S,START1-L,START1-M,START1-S,START1-XS, GP1-XL,GP1-L,GP1-M,GP1-S,GP1-XS

A basic configuration should look like the following example:

  "type": "scaleway",
  "organization_id": "YOUR API ACCESS KEY",
  "api_token": "YOUR TOKEN",
  "image": "UUID OF THE BASE IMAGE",
  "region": "par1",
  "commercial_type": "START1-S",
  "ssh_username": "root",
  "ssh_private_key_file": "/home/user/.ssh/id_rsa"

When you do not specify the ssh_private_key_file, a temporarily SSH keypair will be generated to connect to the server. This key will only allow the root user to connect the server.

There are also some optional parameters that you can use:

  • server_name (string) - The name assigned to the server. Default packer-UUID

  • image_name (string) - The name of the resulting image that will appear in your account. Default packer-TIMESTAMP

  • snapshot_name (string) - The name of the resulting snapshot that will appear in your account. Default packer-TIMESTAMP

  • bootscript (string) - The id of an existing bootscript to use when booting the server.

Building an Image with Packer

As exemplified below, we will build an Ubuntu Image with Apache preinstalled:

1 . Set your credentials as environment variable on your computer. For example in bash, you have to edit the file ~/.bashrc, for zsh the procedure is the same, but the file to edit is ~/.zshrc:


2 . Create and edit the file packer.json by putting the following content in it:

  "variables": {
    "organization_id": "",
    "api_token": ""
  "builders": [
      "organization_id": "{{ user `organization_id` }}",
      "api_token": "{{ user `api_token` }}",
      "server_name": "apache",
      "image_name": "ubuntu-apache",
      "snapshot_name": "ubuntu-apache-snapshot",
      "type": "scaleway",
      "image": "27452e61-310e-4fe5-93af-0a0bdf4c20a6",
      "region": "par1",
      "commercial_type": "START1-S",
      "ssh_private_key_file": "/Users/myaccount/.ssh/id_rsa",
      "ssh_username": "root"
  "provisioners": [
     "type": "shell",
     "inline": [
         "sleep 30",
         "apt-get update",
         "apt-get -y upgrade",
         "apt-get install -y apache2"

3 . Save the file and launch packer:

packer --organization_id $ORGANIZATION_ID --api_token $SCW_TOKEN build packer.json

You will see an output like the following:

$ packer build scaleway.json
scaleway output will be in this color.

==> scaleway: Using existing SSH private key
==> scaleway: Creating server...
==> scaleway: Waiting for server to become active...
==> scaleway: Waiting for SSH to become available...
==> scaleway: Connected to SSH!
==> scaleway: Provisioning with shell script: /var/folders/4k/cgkd9dgs29z98lpyrtwwbsfw0000gn/T/packer-shell978019985
==> scaleway: Shutting down server...
==> scaleway: Creating snapshot: ubuntu-apache-snapshot
==> scaleway: Creating image: ubuntu-apache
==> scaleway: Destroying server...
Build 'scaleway' finished.

==> Builds finished. The artifacts of successful builds are:
--> scaleway: An image was created: 'ubuntu-apache' (ID: e6e764cf-7f46-4c13-b251-a9e47367e284) in region 'par1' based on snapshot 'ubuntu-apache-snapshot' (ID: 7abb7315-fae6-4317-9389-8ecf3c5e8a7b)

And the newly created image will appear in the image list in your account:

Image List

4 . You can now start one or a series of servers with your new image.

Deploying Machine Images with Terraform

1 . Download Terraform for your operating system.

2 . Create a configuration file with the following contents:

provider "scaleway" {
  organization = "<YOUR-ORGANIZATION-ID>"
  token        = "<YOUR-SECRET-TOKEN>"
  region       = "par1"

resource "scaleway_ip" "ip" {

data "scaleway_image" "ubuntu-apache" {
  architecture = "x86_64"
  name         = "ubuntu-apache"

resource "scaleway_instance_volume" "data" {
  size_in_gb = 40
  type = "l_ssd"

resource "scaleway_server" "ubuntu-apache-server" {
  name  = "ubuntu-apache-server"
  public_ip = "${scaleway_ip.ip.ip}"
  image = "${}"
  type  = "DEV1-M"


resource "scaleway_security_group" "http" {
  name        = "http"
  description = "allow HTTP and HTTPS traffic"

resource "scaleway_security_group_rule" "http_accept" {
  security_group = "${}"

  action    = "accept"
  direction = "inbound"
  ip_range  = ""
  protocol  = "TCP"
  port      = 80

resource "scaleway_security_group_rule" "https_accept" {
  security_group = "${}"

  action    = "accept"
  direction = "inbound"
  ip_range  = ""
  protocol  = "TCP"
  port      = 443

3 . Initialize Terraform:

terraform init

You will see an output like the following:

Initializing provider plugins...
- Checking for available provider plugins on
- Downloading plugin for provider "scaleway" (1.5.1)...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

4 . Run a dry run of the configuration to check it:

terraform plan

5 . Start your server from Terraform:

terraform apply

An output like the following will appear on the screen:

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

scaleway_server.test: Creating...
  boot_type:    "" => "<computed>"
  enable_ipv6:  "" => "false"
  image:        "" => "e6e764cf-7f46-4c13-b251-a9e47367e284"
  name:         "" => "ubuntu-apache"
  private_ip:   "" => "<computed>"
  public_ip:    "" => "<computed>"
  public_ipv6:  "" => "<computed>"
  state:        "" => "<computed>"
  state_detail: "" => "<computed>"
  type:         "" => "Start1-S"
scaleway_server.test: Still creating... (10s elapsed)
scaleway_server.test: Still creating... (20s elapsed)
scaleway_server.test: Still creating... (30s elapsed)
scaleway_server.test: Still creating... (40s elapsed)
scaleway_server.test: Creation complete after 47s (ID: d47cbd7b-8ab7-40d3-b7ff-2b8a5d7d2dd4)
scaleway_ip.ip: Modifying... (ID: f2a248eb-6b1e-4019-95ee-1460ba24525e)
  server: "24605678-04f7-4d5f-9b23-9af249af464d" => "d47cbd7b-8ab7-40d3-b7ff-2b8a5d7d2dd4"
scaleway_ip.ip: Modifications complete after 1s (ID: f2a248eb-6b1e-4019-95ee-1460ba24525e)

Apply complete! Resources: 1 added, 1 changed, 0 destroyed.

To find out more about all resources that you can manage with Terraform, check out the official documentation.

Discover a New Cloud Experience

Deploy SSD Cloud Servers in seconds.