Nick Charlton

Automating Ubuntu 20.04 installs with Packer

Ubuntu 20.04 — which was released few days ago (23rd April) — brings with it a new installer, replacing the previous Debian installer with subiquity. This means that any of the previous approaches for automated/unattended installs no longer work and need to be replaced.

No one seemed to have documented doing this successfully yet with Packer, so I set out to figure it out. But first, here’s a working unattended configuration:

ubuntu-2004.json:

{
  "builders": [
    {
      "name": "ubuntu-2004",
      "type": "vmware-iso",
      "guest_os_type": "ubuntu-64",
      "headless": false,

      "iso_url": "http://releases.ubuntu.com/20.04/ubuntu-20.04-live-server-amd64.iso",
      "iso_checksum": "caf3fd69c77c439f162e2ba6040e9c320c4ff0d69aad1340a514319a9264df9f",
      "iso_checksum_type": "sha256",

      "ssh_username": "ubuntu",
      "ssh_password": "ubuntu",
      "ssh_handshake_attempts": "20",

      "http_directory": "http",

      "memory": 1024,

      "boot_wait": "5s",
      "boot_command": [
        "<enter><enter><f6><esc><wait> ",
        "autoinstall ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/",
        "<enter>"
      ]
    }
  ],

  "provisioners": [
    {
      "type": "shell",
      "inline": ["ls /"]
    }
  ]
}

user-data:

#cloud-config
autoinstall:
  version: 1
  identity:
    hostname: ubuntu-server
    password: '$6$wdAcoXrU039hKYPd$508Qvbe7ObUnxoj15DRCkzC3qO7edjH0VV7BPNRDYK4QR8ofJaEEF2heacn0QgD.f8pO8SNp83XNdWG6tocBM1'
    username: ubuntu
  network:
    network:
      version: 2
      ethernets:
        ens33:
          dhcp4: true
          dhcp-identifier: mac
  ssh:
    install-server: true
  late-commands:
    - sed -i 's/^#*\(send dhcp-client-identifier\).*$/\1 = hardware;/' /target/etc/dhcp/dhclient.conf
    - 'sed -i "s/dhcp4: true/&\n      dhcp-identifier: mac/" /target/etc/netplan/00-installer-config.yaml'

We also need the presence of the file meta-data: touch meta-data in the directory available to the Packer HTTP server. The password is ubuntu. Whilst this uses the VMware builder, the relevant configuration options exist among the other builders, too.

I’ve also created an example Github repo with the working configuration in.

The new unattended installation is well documented and I started from the Quick Start guide.

There were four things that need solving on top of the basic configuration:

The typical way to do this is to restore the DHCP identifier used back to the MAC address of the device, rather than the device identifier which is now common. This is the same problem as I’ve seen previously with Debian Buster (10), and I’ve reused the late command here to set the DHCP client to do that. We also seem to need to do this with netplan too, to reliably get the same IP back that Packer is expecting.

Interestingly, subiquity does not seem to support dhcp-identifier and so we need to do this ourselves after the installation is completed. We need to quote the sed line, as otherwise we fall into a trap when loading cloud-init configuration, as it seems to think it’s YAML.

This took quite a bit of time to get working right. To solve issues along the way, I: