Automate Debian Provisioning with virt-install

This article explores virt-install, a command-line provisioning tool for libvirt-based virtualization, and details how it automates the deployment of Debian guest operating systems. Readers will learn the core concepts of virt-install, its integration with the KVM hypervisor, and the exact mechanisms—specifically Debian preseed files and unattended installation flags—used to deploy fully configured Debian virtual machines without manual intervention.


What is virt-install?

virt-install is a command-line utility used to provision new virtual machines (VMs) running on top of hypervisors like KVM (Kernel-based Virtual Machine) and Xen through the libvirt management daemon. It provides an interface to configure hardware parameters—such as CPU cores, memory allocation, storage paths, and network interfaces—while orchestrating the operating system installation process.

Because virt-install operates entirely from the command line, it integrates cleanly into Bash scripts, infrastructure pipelines, and configuration management tools such as Ansible.


The Mechanism of Debian Automation

Standard operating system installations require a user to step through interactive menus to configure localization, network interfaces, disk partitioning, and user accounts. To automate this process for Debian, virt-install pairs network installation sources with Debian's native automation framework: the Preseed file.

A preseed file (preseed.cfg) contains predetermined answers to all questions normally posed by the Debian Installer (debian-installer). When combined with virt-install, the provisioning flow works as follows:

  1. Direct Kernel/Initrd Fetching: Using the --location flag, virt-install retrieves the Debian kernel and initial RAM disk (initrd.gz) directly from a local ISO or a remote Debian mirror (HTTP/FTP).
  2. Passing Installer Arguments: Using the --extra-args flag, parameters are appended directly to the kernel command line. This tells the installer to run non-interactively and points it to the preseed file location.
  3. Unattended Execution: The Debian installer boots, reads the preseed answers, sets up the disks, installs the base system, and configures the environment without manual intervention.

Key Components for Automated Debian Deployment

1. The Preseed Configuration

A preseed.cfg file must be made accessible to the VM during installation, commonly via a local web server (e.g., http://192.168.122.1/preseed.cfg) or embedded into an initrd image. A basic preseed handles:

  • Language and locale settings.
  • Automated network interface selection via DHCP.
  • Disk partitioning schemes (e.g., automated LVM or regular partitions).
  • Root password and default user creation.
  • Package selection (e.g., OpenSSH server).
  • Automatic reboot upon completion.

2. The virt-install Command

To trigger the automated setup, run a command formatted like the following:

virt-install \
  --name debian-guest-01 \
  --ram 2048 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/debian-guest-01.qcow2,size=20,format=qcow2 \
  --os-variant debian12 \
  --network network=default \
  --graphics none \
  --console pty,target_type=serial \
  --location 'http://deb.debian.org/debian/dists/bookworm/main/installer-amd64/' \
  --extra-args 'auto=true priority=critical console=ttyS0,115200n8 preseed/url=http://192.168.122.1/preseed.cfg' \
  --wait -1

Parameter Breakdown:

  • --graphics none & --console pty...: Directs output to a serial console, allowing headless management via the terminal without needing a VNC or SPICE client.
  • --location: Specifies the network repository source for the installer assets.
  • --extra-args:
    • auto=true priority=critical: Suppresses standard interactive prompts and stops only for fatal errors.
    • console=ttyS0,115200n8: Sends the installation log output directly to the terminal serial output.
    • preseed/url=...: Tells the installer where to download the automated answers.
  • --wait -1: Keeps the virt-install process running until the guest finishes installing and reboots, which helps sequential deployment scripts track completion.

Alternative: Native --unattended Option

In modern versions of virt-install, the tool includes a built-in --unattended flag, which abstracts preseed generation via libosinfo.

virt-install \
  --name debian-auto \
  --ram 2048 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/debian-auto.qcow2,size=20 \
  --os-variant debian12 \
  --cdrom /path/to/debian-12.iso \
  --unattended user-password=secret,admin-password=secret

This approach generates a minimal preseed automatically and injects it into the installer, eliminating the need to manually host a preseed.cfg file for basic deployments. However, the manual preseed method remains standard for advanced customizations, custom disk partitioning, and software installation scripts.