DevOps

Ubuntu 24.04 Packer Template for VMware

Learn how to build an Ubuntu 24.04 Packer template for VMware to automate the installation of Ubuntu 24.04 LTS and create a VM template

Now that the release of Ubuntu 24.04 LTS is official with Ubuntu dropping news of the release today of both the new Desktop and Server, it’s time to start updating some automation in the home lab. I wanted to test and see if the framework of automated build templates I had used for Ubuntu 22.04 Server LTS would work with Ubuntu 24.04 LTS, and for the most part they did. So, let’s look at what you will need for installing Ubuntu 24.04 Server LTS using packer.

Why is Packer helpful in vSphere?

You can automatically build and provision new vSphere templates. This capability allows you to schedule or automate the creation and updating of vSphere templates so you always have the latest template available with updates, etc.

Download Packer and vSphere plugin

The first thing you need to do is download Packer and the vSphere ISO plugin. You can download the latest version of Hashicorp Packer here: Download Packer. Select the binary for your specific platform.

Install packer for your platform
Install packer for your platform

Install the vSphere plugin

Once you have Packer installed, we need to download the vSphere plugin. This plugin allows Packer to work with automated builds for VMware vSphere. You can do that with the following command:

packer plugins install github.com/hashicorp/vsphere
Install the vsphere iso plugin
Install the vsphere iso plugin

Now that we have Packer and the vSphere plugin installed, we are ready to automate our Ubuntu 24.04 LTS Server installation.

Ubuntu 24.04 LTS Server Packer template

You will need three files:

  • ubuntu.auto.pkrvars.hcl – Contains the values for the variables file
  • ubuntu-24.04.pkr.hcl – The main Packer build file
  • variables.pkr.hcl – The variables file

Ubuntu.auto.pkrvars.hcl

The contents of the ubuntu.auto.pkrvars.hcl file is as follows:

vsphere_server = "server.domain.local"
vsphere_user = "[email protected]"
vsphere_password = "password"
vsphere_template_name = "ubuntu2404-testtemplate"
vsphere_folder = "Templates"
vsphere_dc_name = "DC name"
cluster = "clustername"
vsphere_host = "host.domain.local"
vsphere_portgroup_name = "DPG-Servers"
vsphere_datastore = "datastore1"
cpu_num = 4
mem_size = 4096
disk_size = 102400
vm_disk_controller_type = ["pvscsi"]

Ubuntu-24.04.pkr.hcl

The contents of the Ubuntu-24.04.pkr.hcl file are as follows. Note below the http_ip isn’t needed in most cases. However, it allows you to specify which IP address you want your remote VM template as it is building, to access. I have found this to be needed especially when you are running Packer from a machine that has more than one network card as Packer will randomly pick the NIC otherwise.

source "vsphere-iso" "autogenerated_1" {
  CPUs                 = 4
  RAM                  = 4096
  boot_command         = ["<esc><esc><esc><esc>e<wait>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "<del><del><del><del><del><del><del><del>", "linux /casper/vmlinuz --- autoinstall ds=\"nocloud-net;seedfrom=http://{{ .HTTPIP }}:{{ .HTTPPort }}/\"<enter><wait>", "initrd /casper/initrd<enter><wait>", "boot<enter>", "<enter><f10><wait>"]
  boot_wait            = "3s"
  cluster              = "${var.cluster}"
  convert_to_template  = true
  datastore            = "${var.vsphere_datastore}"
  disk_controller_type = "${var.vm_disk_controller_type}"
  folder               = "${var.vsphere_folder}"
  guest_os_type        = "ubuntu64Guest"
  http_directory       = "./http"
  http_ip              = "10.1.149.152"
  insecure_connection  = "true"
  iso_checksum         = "sha256:8762f7e74e4d64d72fceb5f70682e6b069932deedb4949c6975d0f0fe0a91be3"
  iso_urls             = ["https://releases.ubuntu.com/24.04/ubuntu-24.04-live-server-amd64.iso"]
  network_adapters {
    network      = "${var.vsphere_portgroup_name}"
    network_card = "vmxnet3"
  }
  password               = "${var.vsphere_password}"
  shutdown_command       = "sudo shutdown -P now"
  ssh_handshake_attempts = "100"
  ssh_password           = "ubuntu"
  ssh_port               = 22
  ssh_timeout            = "20m"
  ssh_username           = "ubuntu"
  storage {
    disk_size             = 40960
    disk_thin_provisioned = true
  }
  username       = "${var.vsphere_user}"
  vcenter_server = "${var.vsphere_server}"
  vm_name        = "${var.vsphere_template_name}"
}

# 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.vsphere-iso.autogenerated_1"]

}

Variables.pkr.hcl

The contents of the variables.pkr.hcl file are as follows:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

variable "ssh_username" {
  type      = string
  default   = ""
  sensitive = true
}

variable "ssh_password" {
  type      = string
  default   = ""
  sensitive = true
}

variable "vm_disk_controller_type" {
  type        = list(string)
  description = "The virtual disk controller types in sequence. (e.g. 'pvscsi')"
  default     = ["pvscsi"]
}

Cloud config

There is one other part of a successful Ubuntu 24.04 LTS packer installation and that is the cloud config customizations.

You will need to create a folder called http in the same folder as the three files we have detailed above. The http folder will house 2 files:

  • user-data
  • meta-data

The meta-data file is just empty. However, the user-data file is the file where we can introduce customizations to the installation like SSH keys and other configuration. In the config below, you will have an Ubuntu installation that will create a user called ubuntu and the hashed password is also ubuntu as I have highlighted.

#cloud-config
autoinstall:
  version: 1
  apt:
    fallback: offline-install
    geoip: true
    preserve_sources_list: false
    primary:
    - arches: [amd64, i386]
      uri: http://gb.archive.ubuntu.com/ubuntu
    - arches: [default]
      uri: http://ports.ubuntu.com/ubuntu-ports
  users:
  - default
  - name: ubuntu
    lock_passwd: false
    passwd: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
  write_files:
  - path: /etc/ssh/sshd_config
    content: |
         Port 22
         Protocol 2
         HostKey /etc/ssh/ssh_host_rsa_key
         HostKey /etc/ssh/ssh_host_dsa_key
         HostKey /etc/ssh/ssh_host_ecdsa_key
         HostKey /etc/ssh/ssh_host_ed25519_key
         UsePrivilegeSeparation yes
         KeyRegenerationInterval 3600
         ServerKeyBits 1024
         SyslogFacility AUTH
         LogLevel INFO
         LoginGraceTime 120
         PermitRootLogin yes
         StrictModes no
         RSAAuthentication yes
         PubkeyAuthentication no
         IgnoreRhosts yes
         RhostsRSAAuthentication no
         HostbasedAuthentication no
         PermitEmptyPasswords no
         ChallengeResponseAuthentication no
         X11Forwarding yes
         X11DisplayOffset 10
         PrintMotd no
         PrintLastLog yes
         TCPKeepAlive yes
         AcceptEnv LANG LC_*
         Subsystem sftp /usr/lib/openssh/sftp-server
         UsePAM yes
         AllowUsers ubuntu
  identity:
    hostname: ubuntu2404
    username: ubuntu
    password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
  ssh:
    allow-pw: true
    install-server: true
  user-data:
    disable_root: false
  locale: en_US
  storage:
    layout:
      name: direct
    config:
      - type: disk
        id: disk0
        match:
          size: largest
      - type: partition
        id: boot-partition
        device: disk0
        size: 500M
      - type: partition
        id: root-partition
        device: disk0
        size: -1
  late-commands:
    - echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/ubuntu

Running the command:

tree /f

We see the following files and folders:

Running the tree command to view the contents of the packer folder
Running the tree command to view the contents of the packer folder

How do you run Packer once all the files are in place?

After you have the files in place in a directory you are working from, you can run the following command to initiate the Packer build command:

First, make sure you have the Proxmox plugin by running the command:

packer init .

Then, you can run the Packer build with the following:

packer build .

Troubleshooting

If you run into errors, you can validate your files using:

packer validate <put your hcl file here>

If variables aren’t correctly recognized, makes sure:

  • There are no typos
  • They correctly exist in both the variables file and the auto.pkr.hcl file

If the Proxmox plugin isn’t recognized, make sure you run:

packer init .

Masking sensitive variables

I know some may read this post and say, you never want to have sensitive variables and other information in plain text. You are right. The files above are meant to be for learning purposes and for quick and dirty VM templates in a home lab environment.

However, for production, you can do a couple of things:

What should you do next?

You can clone down my Packer builds repo on Github that includes the new Ubuntu 24.04 build here:

git clone https://github.com/brandonleegit/PackerBuilds.git

Wrapping up

Hopefully, this post and example files and configurations will help anyone who wants to update their virtual machine templates to Ubuntu 24.04 Server LTS now that the release is official. Packer provides an easy way to do this and automate the entire solution to take the heavy lifting out of the process.

Subscribe to VirtualizationHowto via Email 🔔

Enter your email address to subscribe to this blog and receive notifications of new posts by email.



Brandon Lee

Brandon Lee is the Senior Writer, Engineer and owner at Virtualizationhowto.com, and a 7-time VMware vExpert, with over two decades of experience in Information Technology. Having worked for numerous Fortune 500 companies as well as in various industries, He has extensive experience in various IT segments and is a strong advocate for open source technologies. Brandon holds many industry certifications, loves the outdoors and spending time with family. Also, he goes through the effort of testing and troubleshooting issues, so you don't have to.

Related Articles

9 Comments

    1. Yigal,

      Thank you for your comment! I will add this to the text of the blog. Once you have the files in place, you should be able to run the packer build command as follows: “packer build .” Notice the period at the end of the command.

      Brandon

  1. New sections added “How do you run Packer once all the files are in place?” and “Troubleshooting” to help with troubleshooting any errors.

  2. It would have been great if you had made a tutorial using ubuntu’s cloud images 🙂 I’ve just tried upgrading from 22.04 to 24.04 and it doesn’t work because open-vm-tools (well, the vmtools integrated with cloudinit) don’t seem to recognize the system when running a guest info command, I can see that in the cloudinit logs. The consequence is that packer clones the VM succesfully, but the network interface is never connected. After connecting it, packer starts running the ansible role.

    1. letharson,

      Thank you for the comment! Hmmm…I haven’t worked with the cloud images using packer. Wondering if this is a compatibility issue with 24.04 being new. What are your observations? However, it sounds like they are getting installed, just not automatically connecting?

      Brandon

    2. You may try this little trick I had to use on Ubuntu 22.04 – open-vm-tools seemed to think “22.04” was an old distribution, and tried some old way of doing things – by changing version in /etc/issue, the guest customization network configuration worked. You can try to change “24.04” in /etc/issue to “22.04” or to “18.04” to see if that works…

      provisioner “shell” {
      inline = [
      “echo ‘*** Fake Ubuntu version 18.04 so that open-vm-tools guest customization works ***'”,
      “echo ‘${var.ssh_password}’ | sudo -S sed -i ‘s/Ubuntu 22.04/Ubuntu 18.04/’ /etc/issue”
      ]
      }

  3. It would be great if you offered a tutorial for Ubuntu 24.04 cloud image too, so that you don’t have to wait for the whole installer when provisioning templates 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.