bento icon indicating copy to clipboard operation
bento copied to clipboard

HCL 2 migration

Open boldandbusted opened this issue 4 years ago • 4 comments

As of Packer 1.7, HCL 2 is now the default, 'blessed' language of Packer. It's probably a good idea to start exploring the next steps toward an HCL 2 future - while identifying likely roadblocks, and file Issues (or make PRs!) with the upstream Packer project if workarounds create too much friction for Bento's development.

Motivation

As a developer-user, I want to consider using HCL 2 in the Bento Packer templates, so that the Bento Project maintains compatibility with the Packer upstream requirements and methodologies.

Specification (Strategy)

  • All current JSON is converted to HCL 2 successfully - and any anomalies are reported to the Packer project.

Specification (Tactics)

  • Try out the various automatic conversion paths from JSON to HCL 2 the Packer project provides.
  • Identify JSON approaches that are not covered by HCL 2 (and establish if there is work in progress or that they are abandoned approaches)
  • Guesstimate how long the conversions will take.
  • Identify if there can be a gradual, incremental conversion of current JSON templates, or if a 'measure twice, cut once' approach is best.
  • Adjust any JSON-dependent tests.

Downstream Impact

All tools and development workflows are likely impacted by this work, including any external tools that take advantage of JSON-based Packer templates. Any JSON-related CI tests will be impacted.

P.S. No, I'm not a dev with Bento, but I've benefited greatly from Bento's work. I hope you-all don't mind me starting this off - please feel free to delete if this is inappropriate. I want to assist as best I can in converting the existing templates, and identifying issues and bugs.

boldandbusted avatar Jul 20 '21 16:07 boldandbusted

I would really like to move to HCL2. It's so much easier to understand what's going on in the code. The auto migration seems to mostly work. There's a bit of cleanup to handle after this. If someone wanted to start that process it would be great. Otherwise it might be quite a while before we have cycles to do this.

tas50 avatar Sep 18 '21 19:09 tas50

I had to add the plugin manually, but here is ubuntu-20.04-arm64.

packer hcl2_upgrade -with-annotations ubuntu-20.04-arm64.json

ubuntu-20.04-arm64.json.pkr.hcl

packer {
  required_plugins {
    parallels = {
      version = ">= 1.0.0"
      source  = "github.com/hashicorp/parallels"
    }
  }
}

# This file was autogenerated by the 'packer hcl2_upgrade' command. We
# recommend double checking that everything is correct before going forward. We
# also recommend treating this file as disposable. The HCL2 blocks in this
# file can be moved to other files. For example, the variable blocks could be
# moved to their own 'variables.pkr.hcl' file, etc. Those files need to be
# suffixed with '.pkr.hcl' to be visible to Packer. To use multiple files at
# once they also need to be in the same folder. 'packer inspect folder/'
# will describe to you what is in that folder.

# Avoid mixing go templating calls ( for example ```{{ upper(`string`) }}``` )
# and HCL2 calls (for example '${ var.string_value_example }' ). They won't be
# executed together and the outcome will be unknown.

# All generated input variables will be of 'string' type as this is how Packer JSON
# views them; you can change their type later on. Read the variables type
# constraints documentation
# https://www.packer.io/docs/templates/hcl_templates/variables#type-constraints for more info.
variable "box_basename" {
  type    = string
  default = "ubuntu-20.04-arm64"
}

variable "build_directory" {
  type    = string
  default = "../../builds"
}

variable "cpus" {
  type    = string
  default = "2"
}

variable "disk_size" {
  type    = string
  default = "65536"
}

variable "git_revision" {
  type    = string
  default = "__unknown_git_revision__"
}

variable "guest_additions_url" {
  type    = string
  default = ""
}

variable "headless" {
  type    = string
  default = ""
}

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

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

variable "hyperv_generation" {
  type    = string
  default = "2"
}

variable "hyperv_switch" {
  type    = string
  default = "bento"
}

variable "iso_checksum" {
  type    = string
  default = "fef8bc204d2b09b579b9d40dfd8c5a084f8084a9bffafe8a0f39a0e53606312d"
}

variable "iso_name" {
  type    = string
  default = "ubuntu-20.04.4-live-server-arm64.iso"
}

variable "memory" {
  type    = string
  default = "1024"
}

variable "mirror" {
  type    = string
  default = "http://cdimage.ubuntu.com"
}

variable "mirror_directory" {
  type    = string
  default = "releases/20.04/release"
}

variable "name" {
  type    = string
  default = "ubuntu-20.04-arm64"
}

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

variable "preseed_path" {
  type    = string
  default = "preseed.cfg"
}

variable "template" {
  type    = string
  default = "ubuntu-20.04-arm64"
}

variable "version" {
  type    = string
  default = "TIMESTAMP"
}
# The "legacy_isotime" function has been provided for backwards compatability, but we recommend switching to the timestamp and formatdate functions.

# All locals variables are generated from variables that uses expressions
# that are not allowed in HCL2 variables.
# Read the documentation for locals blocks here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/locals
locals {
  build_timestamp = "${legacy_isotime("20060102150405")}"
  http_directory  = "${path.root}/http"
}

# source blocks are generated from your builders; a source can be referenced in
# build blocks. A build block runs provisioner and post-processors on a
# source. Read the documentation for source blocks here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/source
source "parallels-iso" "autogenerated_1" {
  boot_command           = ["<esc>", "linux /casper/vmlinuz", " quiet", " autoinstall", " ds='nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/'", "<enter>", "initrd /casper/initrd<enter>", "boot<enter>"]
  boot_wait              = "5s"
  cpus                   = "${var.cpus}"
  disk_size              = "${var.disk_size}"
  guest_os_type          = "ubuntu"
  http_directory         = "${local.http_directory}"
  iso_checksum           = "${var.iso_checksum}"
  iso_url                = "${var.mirror}/${var.mirror_directory}/${var.iso_name}"
  memory                 = "${var.memory}"
  output_directory       = "${var.build_directory}/packer-${var.template}-parallels"
  parallels_tools_flavor = "lin-arm"
  prlctl_version_file    = ".prlctl_version"
  shutdown_command       = "echo 'vagrant' | sudo -S shutdown -P now"
  ssh_password           = "vagrant"
  ssh_port               = 22
  ssh_timeout            = "10000s"
  ssh_username           = "vagrant"
  vm_name                = "${var.template}"
}

# a build block invokes sources and runs provisioning steps on them. The
# documentation for build blocks can be found here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/build
build {
  sources = ["source.parallels-iso.autogenerated_1"]

  provisioner "shell" {
    environment_vars  = ["HOME_DIR=/home/vagrant", "http_proxy=${var.http_proxy}", "https_proxy=${var.https_proxy}", "no_proxy=${var.no_proxy}"]
    execute_command   = "echo 'vagrant' | {{ .Vars }} sudo -S -E sh -eux '{{ .Path }}'"
    expect_disconnect = true
    scripts           = ["${path.root}/scripts/update.sh", "${path.root}/../_common/motd.sh", "${path.root}/../_common/sshd.sh", "${path.root}/scripts/networking.sh", "${path.root}/scripts/sudoers.sh", "${path.root}/scripts/vagrant.sh", "${path.root}/../_common/parallels.sh", "${path.root}/scripts/hyperv.sh", "${path.root}/scripts/cleanup.sh", "${path.root}/../_common/minimize.sh"]
  }

  post-processor "vagrant" {
    output = "${var.build_directory}/${var.box_basename}.<no value>.box"
  }
}

jhgorse avatar Mar 31 '22 16:03 jhgorse

If I were to take this on, I'd prefer a smart-lazy approach. :) Something like "mass-convert all packer templates, and then see what breaks in testing, then iterate on the brokenness." Is this a reasonable approach? Is there a limit to the testing I should be considering first?

boldandbusted avatar Apr 07 '22 18:04 boldandbusted

Seems reasonable.

What could go wrong? =)

jhgorse avatar Apr 07 '22 19:04 jhgorse

This has been completed in the latest release of the code.

Stromweld avatar Jan 20 '23 00:01 Stromweld