Packer

Hetzner inline script

# set api token
> export HCLOUD_TOKEN="XXX"
provider.pkr.hcl
packer {
  required_plugins {
    hcloud = {
      source  = "github.com/hetznercloud/hcloud"
      version = ">= 1.2.0"
    }
  }
}
hcloud-inline.pkr.hcl
variable "base_image" {
  type    = string
  default = "debian-12"
}
variable "output_name" {
  type    = string
  default = "snapshot-v1.0.0"
}

source "hcloud" "base-amd64" {
  image         = var.base_image
  location      = "nbg1"
  server_type   = "cx11"
  ssh_username  = "root"
  snapshot_name = "${var.output_name}"
  snapshot_labels = {
    base    = var.base_image,
    name    = "${var.output_name}"
  }
}

build {
  sources = ["source.hcloud.base-amd64"]
  provisioner "shell" {
    inline = [
      "apt-get install -y wget",
      "touch /etc/foo.txt",
    ]
  }
}
# load modules
> packer init provider.pkr.hcl

# run build command
> packer build hcloud-inline.pkr.hcl

Hetzner script config

# set api token
> export HCLOUD_TOKEN="XXX"
provider.pkr.hcl
packer {
  required_plugins {
    hcloud = {
      source  = "github.com/hetznercloud/hcloud"
      version = ">= 1.2.0"
    }
  }
}
hcloud-script-config.pkr.hcl
variable "base_image" {
  type    = string
  default = "debian-12"
}
variable "output_name" {
  type    = string
  default = "snapshot-v1.0.0"
}

source "hcloud" "base-amd64" {
  image         = var.base_image
  location      = "nbg1"
  server_type   = "cx11"
  ssh_username  = "root"
  snapshot_name = "${var.output_name}"
  snapshot_labels = {
    base    = var.base_image,
    name    = "${var.output_name}"
  }
}

build {
  sources = ["source.hcloud.base-amd64"]
  provisioner "shell" {
    scripts = [
      "os-setup.sh",
    ]
  }
}
os-setup.sh
#!/bin/bash
set -e -o pipefail

apt-get update
apt-get install -y --no-install-recommends wget fail2ban
# load modules
> packer init provider.pkr.hcl

# run build command
> packer build hcloud-script.pkr.hcl

Hetzner cloud-config

# set api token
> export HCLOUD_TOKEN="XXX"
provider.pkr.hcl
packer {
  required_plugins {
    hcloud = {
      source  = "github.com/hetznercloud/hcloud"
      version = ">= 1.2.0"
    }
  }
}
hcloud-cloud-config.pkr.hcl
variable "base_image" {
  type    = string
  default = "debian-12"
}
variable "output_name" {
  type    = string
  default = "snapshot-v1.0.0"
}
variable "user_data_path" {
  type    = string
  default = "cloud-init-default.yml"
}

source "hcloud" "base-amd64" {
  image         = var.base_image
  location      = "nbg1"
  server_type   = "cx11"
  user_data     = file(var.user_data_path)
  ssh_username  = "root"
  snapshot_name = "${var.output_name}"
  snapshot_labels = {
    base    = var.base_image,
    name    = "${var.output_name}"
  }
}

build {
  sources = ["source.hcloud.base-amd64"]
  provisioner "shell" {
    scripts = [
      "os-setup.sh",
    ]
  }
}
cloud-init-default.yml
#cloud-config
#interpreter line is required for cloud-config
users:
  - name: foobert
    groups: users, admin
    sudo: ALL=(ALL) NOPASSWD:ALL
    shell: /bin/bash
    ssh_authorized_keys:
      - ssh-rsa AAAA

packages:
  - fail2ban
  - ufw
package_update: true
package_upgrade: true

runcmd:
  - systemctl enable fail2ban
  - ufw allow OpenSSH
  - ufw enable
os-setup.sh
#!/bin/bash
set -e -o pipefail

echo "waiting for cloud-init"
cloud-init status --wait

apt-get update
apt-get install --yes --no-install-recommends wget fail2ban

echo "cleanup"
cloud-init clean --machine-id --seed --logs
rm -rvf /var/lib/cloud/instances /etc/machine-id /var/lib/dbus/machine-id /var/log/cloud-init*
# load modules
> packer init provider.pkr.hcl

# run build command
> packer build hcloud-cloud-config.pkr.hcl