HCL 2 migration
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.
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.
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"
}
}
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?
Seems reasonable.
What could go wrong? =)
This has been completed in the latest release of the code.