Recently I built up a virtual machine template on Proxmox using Packer. Here below I am going to show which steps were followed in order to achive the aim. I am going to set up VM with CentOS 8 Stream on board.

Installing Packer

Here is shown how to install Packer. Generally, I used the following steps for installing a required packages on my Fedora Workstation:

Installing official HarshiCorp repository:

sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

If yum-config-manager is not available on the host, install yum-utils package: sudo yum install -y yum-utils

And install packer:

sudo yum -y install packer

And that’s it. Packer is installed. Check it:

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

Available commands are:
    build           build image(s) from template
    console         creates a console for testing variable interpolation
    fix             fixes templates from old versions of packer
    fmt             Rewrites HCL2 config files to canonical format
    hcl2_upgrade    transform a JSON template into an HCL2 configuration
    init            Install missing plugins or upgrade plugins
    inspect         see components of a template
    plugins         Interact with Packer plugins and catalog
    validate        check that a template is valid
    version         Prints the Packer version

[admin@workstation packer]$ packer --version
1.8.0
[admin@workstation packer]$ 

Create a hcl file

In order to set up a vm we need to declare a file with instructions for packer. There are two type of files: JSON files and HCL file.

I used to apply following hcl file for my task. The file is starting by defining required plugins. This plugin will be installed using packer init hcls/. In the following part are being declared variables. I declared proxmox_api_url, proxmox_api_token_id and proxmox_api_token_secret. These variables are able to define in the external file, by passing as a command parameter and by defining in the the same hcl file. In my task I set the 2 variables in a external file and secret I gave in command line as a parameter.

Second part of the file is consisting of source part. Here are defined main parameters of the VM, iso file, disk, network and etc.

Third part is the building part what actually runs building process and after provisioning tasks.


packer {
  required_plugins {
    proxmox = {
      version = ">= 1.0.6"
      source  = "github.com/hashicorp/proxmox"
    }
  }
}

variable "proxmox_api_url" {
  type = string
}

variable "proxmox_api_token_id" {
  type = string
}

variable "proxmox_api_token_secret" {
  type      = string
  sensitive = true
}

source "proxmox" "centos8-packer" {
  proxmox_url = "${var.proxmox_api_url}"
  username    = "${var.proxmox_api_token_id}"
  token    = "${var.proxmox_api_token_secret}"

  insecure_skip_tls_verify = true

  node  = "proxmox"
  vm_id = "108"
  vm_name = "centos8-packer"
  template_description = "centos8-packer description"

  iso_file         = "ocp1:iso/CentOS-Stream-8-x86_64-latest-dvd1.iso"

  iso_storage_pool = "local"
  unmount_iso      = true

  qemu_agent = true

  scsi_controller = "virtio-scsi-pci"

  disks {
    disk_size         = "15G"
    format            = "vmdk"
    storage_pool      = "ocp1"
    storage_pool_type = "directory"
    type              = "virtio"
  }

  cores = "2"

  memory = "4096"

  network_adapters {
    model = "virtio"
    bridge = "vmbr0"
    firewall = "false"
   } 

  cloud_init              = true
  cloud_init_storage_pool = "ocp1"

  boot_command = [
    "<tab><bs><bs><bs><bs><bs>text inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.conf<enter><wait><enter>"
  ]
  boot      = "c"
  boot_wait = "5s"

  http_directory = "http" 

  ssh_username = "admin"
  ssh_private_key_file = "~/.ssh/id_rsa"
  ssh_password = "admin"
  ssh_port = 22
  ssh_timeout = "30m"

}

build {
    source "proxmox.centos8-packer" {
        name = "centos8-packer"
    }

    provisioner "shell" {
      inline = [
        "echo Installing Updates",
        "yum update -y",
        "yum install -y cloud-init qemu-guest-agent cloud-utils-growpart gdisk",
      ]

      only = ["proxmox"]
    }
}

By running packer creates a temporary http server using a randomly generated port. Such approach allows to download a kicstart file during installation and set up a machine. Kickstart file is located in http folder (http_directory = "http"). The kickstart file that I used for this task is shared on github. Link

Running Packer

First of all we need to install required plugin for packer.

[admin@workstation packer]$ packer init hcls/
Installed plugin github.com/hashicorp/proxmox v1.0.8 in "/home/admin/.config/packer/plugins/github.com/hashicorp/proxmox/packer-plugin-proxmox_v1.0.8_x5.0_linux_amd64"

And check installed plugin:

[admin@workstation packer]$ packer plugins installed
/home/admin/.config/packer/plugins/github.com/hashicorp/proxmox/packer-plugin-proxmox_v1.0.8_x5.0_linux_amd64

Next step is setting up a machine.

[admin@workstation packer]$ packer build -var-file='creds.pkr.hcl' -var proxmox_api_token_secret="<my-secret>" hcls/proxmox-centos.pkr.hcl
proxmox.centos8-packer: output will be in this color.

==> proxmox.centos8-packer: Creating VM
==> proxmox.centos8-packer: Starting VM
==> proxmox.centos8-packer: Starting HTTP server on port 8665
==> proxmox.centos8-packer: Waiting 5s for boot
==> proxmox.centos8-packer: Typing the boot command
==> proxmox.centos8-packer: Waiting for SSH to become available...
==> proxmox.centos8-packer: Connected to SSH!
==> proxmox.centos8-packer: Stopping VM
==> proxmox.centos8-packer: Converting VM to template
==> proxmox.centos8-packer: Adding a cloud-init cdrom in storage pool ocp1
Build 'proxmox.centos8-packer' finished after 8 minutes 35 seconds.

==> Wait completed after 8 minutes 35 seconds

==> Builds finished. The artifacts of successful builds are:
--> proxmox.centos8-packer: A template was created: 108

[admin@workstation packer]$ 

Reference

Tags:

Updated: