sync-host-keys.sh: generates/registers SSH host keys and their .sops.yaml/secrets/*.yaml recipients for flake targets, idempotently. --all, <target>, --remove, --regenerate-all-keys, all with --dry-run (verified zero-side-effect via a sandboxed git-status check across every mode). Only ever touches anchors with a corresponding host-keys/ file -- &admin and any hand-registered real-host anchor are never listed, removed, or regenerated. Supersedes running prepare-host-key.sh one host at a time for any target that already has a flake entry. create-proxmox-resource.sh: builds a lxc-*/proxmox-* target's tarball/disk image and creates it on a real Proxmox node, or reconfigures an existing resource's cores/memory/disk (--modify, always requires typing the VMID back to confirm). Refuses to create a new resource for a VMID that already exists, and refuses to duplicate a host identity that already has a real deployment elsewhere (variables.nix's new deployedTargets, checked by hostName so it also catches cross-platform duplicates) unless --allow-duplicate-host is passed. --dry-run throughout. scripts/env.sh centralizes the Proxmox connection config both scripts (and future ones) share. Also fixes an unrelated gap found along the way: proxmox-* Disko image builds write their .raw file straight into the repo root, and .gitignore never covered it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01La55Nsss8jZ7ZuzUV9mfot
4.3 KiB
Proxmox VM disk images
proxmox-* hosts (VM platform, not lxc-*) can be built as standalone,
ready-to-attach .raw disk images via disko's own image-builder — no
nixos-install, no live installer boot. This uses the same disko.devices
config (modules/disko/proxmox.nix) already used to format a real disk on
install, so there's nothing host-specific to write; it's available for every
proxmox-* target automatically.
scripts/create-proxmox-resource.sh --type vm --host <name> automates the
whole walkthrough below (and the equivalent LXC one) end to end, including
host-key handling and upload — see its --help. The steps here are what it
runs under the hood, useful for doing any of it by hand or understanding
what it does before you trust it against real infrastructure.
Building
nix build .#nixosConfigurations.proxmox-server.config.system.build.diskoImagesScript
sudo ./result --build-memory 2048
This produces <hostname>.raw in the current directory (e.g. server.raw
for proxmox-server, matching networking.hostName, not the flake attribute
name — every proxmox-* host gets a distinctly named image instead of all
of them producing an identical main.raw). The script builds inside a
temporary QEMU VM and moves the finished image out to the working directory
when done; --build-memory controls how much RAM that build VM gets.
disko.devices.disk.main.imageSize (currently 20G, in
modules/disko/proxmox.nix) sets the image's total size — disko doesn't
support auto-resizing, so this needs to comfortably fit ESP + swap + root at
build time. Grow the virtual disk (and resize the filesystem) in Proxmox
after attaching if a host needs more than that; this is the normal way to
size these images, not a one-time decision to get exactly right up front.
Host keys
The disko image script runs a real activation pass inside its temporary
build VM while constructing the image — the same sops-nix
activation-before-first-boot problem the installer and LXC tarball workflows
have (see docs/auto-installer.md) applies here too, unmodified. Disko has
a native mechanism for it:
sudo ./result \
--pre-format-files host-keys/server_ssh_host_ed25519_key /etc/ssh/ssh_host_ed25519_key \
--pre-format-files host-keys/server_ssh_host_ed25519_key.pub /etc/ssh/ssh_host_ed25519_key.pub \
--build-memory 2048
Generate the key first with scripts/sync-host-keys.sh <hostname>, same
as any other host — see docs/auto-installer.md for the full walkthrough
(it registers the new key in .sops.yaml and re-encrypts the affected
secrets/*.yaml files too, no manual editing needed).
Deploying to Proxmox
The image needs UEFI (OVMF), not Proxmox's default SeaBIOS —
modules/boot/efi.nix uses systemd-boot, which only works with UEFI
firmware. virtio-scsi is safe to use as the disk bus:
hardware-configuration/vm/proxmox.nix already includes virtio_scsi in
its initrd kernel modules.
-
Copy the image to the Proxmox host:
scp server.raw root@<proxmox-host>:/var/lib/vz/import/ -
Create an empty VM shell (no disk yet) — replace
<vmid>with a free ID and<storage>with your storage pool's name (pvesm statusor Datacenter → Storage in the web UI):qm create <vmid> --name proxmox-server --memory 2048 --cores 2 \ --net0 virtio,bridge=vmbr0 \ --bios ovmf --machine q35 \ --scsihw virtio-scsi-pci \ --efidisk0 <storage>:1,efitype=4m,pre-enrolled-keys=0(
--efidisk0is required for UEFI — it's where OVMF persists boot-entry NVRAM; without it, systemd-boot's boot entry may not survive a reboot.) -
Import the raw disk into storage:
qm importdisk <vmid> /var/lib/vz/import/server.raw <storage>This prints the resulting disk identifier (e.g.
vm-<vmid>-disk-1). -
Attach it and set it as the boot disk:
qm set <vmid> --scsi0 <storage>:vm-<vmid>-disk-1 qm set <vmid> --boot order=scsi0 -
Boot it:
qm start <vmid>
No install step — it boots straight into the already-activated system.
Why not nix build .#nixosConfigurations.<host>.config.system.build.vm?
That's a different, unrelated feature — system.build.vm (nixos-rebuild build-vm) produces an ephemeral QEMU script for locally testing a
configuration, not a distributable disk image. It's not part of this
workflow.