Skip to content

Design Spec: Proxmox VM Configuration for hl02

Implementation Status

Component / Feature Status Details
Logical Host Config Fully Implemented Pinned hostname, DHCP, state version defined.
Physical Host Config Fully Implemented Standard physical entrypoint defined.
Disk Layout (Disko) Fully Implemented GPT, 512M ESP, 100% ext4 root partition defined.
Terraform VM Resource Fully Implemented hl02 VM hardware definition added to workloads.
Host Integration Test Fully Implemented Automatically generated by flake for host configs.

1. Goal

Configure hl02 as a fully defined NixOS Proxmox VM using DHCP, defined declaratively with Disko partitioning, and provisioned automatically via Terraform and nixos-anywhere.

2. Rationale

Currently, the configuration for hl02 is incomplete and references a non-existent ext4 role, which prevents it from building. This spec defines the specific configuration, partitioning, and provisioning parameters for hl02 to bring it into a fully declarative state.

It builds upon the global Home Lab Bootstrapping Spec for installation and the Declarative Integration Testing Spec for CI/CD validation.

3. Proposed Changes

3.1 Host Configuration Split

Following the standard logical/physical split (see Testing Spec - Split Design), the files for hl02 are structured under config/nix/hosts/hl02/:

  • default.nix (Physical Entrypoint):
    • Imports ./configuration.nix (logical settings).
    • Imports ./hardware.nix (hardware placeholder).
    • Imports ./disko.nix (filesystem configuration).
  • configuration.nix (Logical Config):
    • Imports roles/common and roles/proxmox-vm (general VM optimizations).
    • Defines logical host parameters:
      • networking.hostName = "hl02"
      • networking.hostId = "92bbb1e6"
      • networking.useDHCP = true
      • system.stateVersion = "25.11"
  • disko.nix (Filesystem Config):
    • Accepts { inputs, ... } globally via specialArgs.
    • Imports the core Disko module (inputs.disko.nixosModules.disko).
    • Defines the physical ext4 disk layout on /dev/sda.
  • hardware.nix (Hardware Placeholder):
    • Left as an empty placeholder { ... } since standard VM hardware configurations (VirtIO drivers, systemd-boot) are generalized in the roles/proxmox-vm role.

3.1.1 ISO Artifact Delivery

To bridge the local Nix build pipeline with the hypervisor environment, the compiled ISO must be staged on the Proxmox target node prior to VM orchestration.

  • Mechanism: Handled declaratively via the proxmox_virtual_environment_file resource within the Terraform workspace.
  • Source Target: The local Nix flake build output directory (./result/iso/\*.iso).
  • Destination Target: Stored in the cluster's default structural storage (local:iso/).
  • Staging: Build the proxmox-images aggregate package before running Terraform, so the ISO coexists behind result with the other image artifacts Terraform reads.

3.2 File System Layout (disko.nix)

Declares a GPT partition table on the primary SCSI virtual disk (/dev/sda):

  • EFI Partition (ESP): 512MB, formatted as vfat, mounted at /boot with standard secure mount options.
  • Root Partition: 100% of the remaining space, formatted as ext4, mounted at /.

3.3 Host-Specific Integration Test

Integration tests are automatically generated and registered for all hosts containing a configuration.nix file.

The flake dynamically discovers config/nix/hosts/hl02/configuration.nix and creates the host-hl02-test check using the global test generator config/nix/tests/make-test.nix.

Because the hl02 configuration imports roles/common (enabling SSH) and roles/proxmox-vm (enabling the QEMU Guest Agent), the auto-generated test automatically verifies:

  1. Successful boot (multi-user.target reached).
  2. SSH port 22 availability.
  3. QEMU Guest Agent service status.

If host-specific custom assertions or configuration overrides are needed in the future, they can be defined in config/nix/hosts/hl02/test-override.nix, which is automatically merged by the flake. A dedicated test.nix entrypoint is not required.

This test is automatically verified in CI (see Testing Spec - Dynamic Discovery).

4. Infrastructure Provisioning (Terraform)

We declare the VM hardware configuration in config/terraform/220-proxmox-workloads/vms-pve1.tf using the bpg/proxmox provider:

  • VM Resource (proxmox_virtual_environment_vm.hl02):
    • Hardware: 2 Cores (Host type), 4GB dedicated RAM, virtio-scsi-pci controller.
    • EFI Disk & Storage: EFI type 4m, stored on local-zfs pool.
    • Disk Interface (scsi0): Presents the virtual disk as /dev/sda inside the VM, matching disko.nix expectations.
    • Storage Optimization: Enables discard = "on" (TRIM) to reclaim unused blocks dynamically on the underlying ZFS pool.
    • Installer CDROM (ide2): Mounts the custom installer ISO (uploaded automatically as described in Bootstrapping Spec - Custom ISO).
    • MAC Pinning: Pins a static MAC address (BC:24:11:D4:F6:65) to the virtio network interface.
    • Automated Boot Order: Configures boot_order = ["scsi0", "ide2"].
      • First Boot: VM disk /dev/sda is empty, falls back to booting from the installer ISO on ide2.
      • Subsequent Boots: Boots directly from the production system on /dev/sda (scsi0), bypassing the installer.

5. Assumptions & Constraints

5.1 Disk Device Configuration (/dev/sda)

The physical Disko configuration explicitly targets /dev/sda. This assumes the Proxmox VM is provisioned using a VirtIO SCSI (virtio-scsi-pci) controller. If the VM is provisioned using a VirtIO Block controller, the disk will present as /dev/vda and partitioning will fail.

  • Constraint: The VM must use a VirtIO SCSI disk interface (scsi0) in Terraform to maintain support for TRIM/Discard on thin-provisioned ZFS pools.

5.2 Networking (DHCP "For Now")

The host uses DHCP for simplicity in this phase. Transitioning to static IPs can be done in a future specification.

Host-Specific Parameters

  1. Router DHCP Reservation: Map MAC address BC:24:11:D4:F6:65 to the designated IP for hl02 in your router.
  2. Installation Command:
    nix develop .#operations -c nixos-anywhere --flake .#hl02 root@hl02.<fqdn>