Skip to content

Builder Playbook

Cloud Codger edited this page Sep 4, 2026 · 1 revision

Build machine

Create an LXC container (CT) and use it to pre-install packages into cloud-init images so they are immediately available when a VM built from one of them first boots.

The builder.yml playbook will update one or more cloud-init images by installing the qemu-guest-agent so it can be used to create VMs that have the guest agent enabled. Thus providing the ability to get a DHCP assigned IP address from the agent using automation.

The playbook also provides a real world example of creating a CT and then configuring it within the same playbook. When a CT uses DHCP, there are challenges in getting the IP address for Ansible to use, which is needed in order to configure it. This lead to the creation of the cloudcodger.proxmox_client.add_guest_host role used here.

Showcased roles

  • cloudcodger.assorted_apt.initial_apt_update
  • cloudcodger.proxmox_client.add_guest_host
  • cloudcodger.proxmox_client.lxc

The Process

  • Create an LXC container (CT) named builder, if it doesn't exist.
  • Perform apt update and apt upgrade so the CT has the latest packages.
  • Download (when src starts with http) or upload cloud-init image(s) to the CT.
  • Install acl and qemu-guest-agent packages into image(s).
    • Includes --update, which also does an apt update for the image(s).
  • Run virt-sysprep to clean up the image(s).
  • Run virt-sparsify --compress to make the image(s) as small as possible.
  • Download the newly updated image(s) to the files directory.

Prerequisites

Commands

Run the playbook on either the single node or the lab cluster.

ansible-playbook -i basic builder.yml
ansible-playbook -i lab-minimal builder.yml

Once finished and no longer needing the CT, remove it.

ansible-playbook -i basic pve_remove_guests.yml -e remove_host_patterns=builder
ansible-playbook -i lab-minimal pve_remove_guests.yml -e remove_host_patterns=builder

Playbook

The builder.yml playbook contains three plays.

  1. Skip creation play.
  2. Create CT play.
  3. Update cloud init images play.

The playbook does not attempt to skip any of the image update tasks, as running the playbook is only needed when one or more files are to be updated. Edit the images variable in the lab/host_vars/builder.yml file to set which cloud-init image(s) to update.

Skip creation play

Due to a known bug in the community.proxmox.proxmox role, this play will remove any existing CTs from lxc_cts so they will not be included in those to be created. This may also be something that is desired when updating any existing CTs is not desired and done to get the playbook runtime lower.

This play may eventually be removed, once the bug is fixed. For now, the solution is to simply skip calling the role for an existing CT.

Create CT play

Runs on local_builder, which is an alias in the lab-minimal inventory directory.

Roles run:

  • cloudcodger.proxmox_client.lxc to:
    • Create the builder CT
  • cloudcodger.proxmox_client.add_guest_host to:
    • Add the host to Ansible inventory with ansible_host set to the IP address. Required for DHCP assigned IP address that is not resolvable via DNS and not using want_facts: true in dynamic inventory.

Update cloud init image files play

The second play runs on the builder host and has settings in lab/host_vars/builder.yml.

Roles run:

  • cloudcodger.ubuntu.initial_apt_update to:
    • run apt dist-upgrade
    • reboot the CT if needed

See the playbook for the tasks that get run in order to put the cloud-init images on the CT, update the images and install additional packages into them, compress the images and "sysprep" the images to clean up any pre-configured items.

Additional Information

Proxmox VE supports the QEMU Guest Agent for QEMU VMs which requires the VM to have the qemu-guest-agent package installed. When creating a large number of VMs in a Proxmox VE cluster, it will save time to pre-install this package into an image used for creating the VMs. When creating VMs that use DHCP to obtain an IP address and using the QEMU Guest Agent to obtain the IP address, it must already exist on the VM when it boots.

This playbook can either download the image from a URL or copy one from the files/ directory (which is not committed to the git repository). It then installs the guest agent into the image file and downloads the resulting updated image to the files/ directory. Since the original cloud-init image may also be used to create VMs, downloading it first and using it to create the updated image is usually best.

The umbrella.yml playbook can be used to verify that an updated Ubuntu image works.

Example commands

Create the CT, update the Cloud-init image to include the QEMU guest agent and download the new image to the files directory. Before running the playbook, update the images variable in the lab/host_vars/builder.yml file to contain the src and dest for image files to be updated.

Clone this wiki locally