Skip to content

Operate Shared VyOS Image Build Pipeline (HyOps)

Build one canonical VyOS disk artifact locally, optionally publish it to object storage, and publish the shared artifact contract consumed by the Proxmox and Hetzner VyOS seed modules.

Module:

  • core/shared/vyos-image-build

Use this when you want HybridOps to own the reproducible build-and-publish step instead of only registering a pre-existing artifact URL.

Typical validation:

hyops validate --env dev --skip-preflight \
  --module core/shared/vyos-image-build \
  --inputs modules/core/shared/vyos-image-build/examples/inputs.min.yml

Typical apply:

hyops apply --env dev \
  --module core/shared/vyos-image-build \
  --inputs modules/core/shared/vyos-image-build/examples/inputs.min.yml

State-first object-repo variant:

hyops apply --env dev \
  --module core/shared/vyos-image-build \
  --inputs modules/core/shared/vyos-image-build/examples/inputs.gcs-state.yml

Expected operator pattern:

  1. build_command creates the local disk artifact from the pinned VyOS ISO.
  2. publish_command uploads that artifact to a stable bucket/object URL.
  3. repo_state_ref is the preferred way to tell the publish helper where that bucket lives.
  4. For GCS publish without Google CLI tools on the builder, provide:
  5. HYOPS_VYOS_GCS_SA_JSON, or
  6. HYOPS_VYOS_GCS_SA_JSON_FILE The publish path materializes inline JSON to a temporary 0600 file on the builder and passes only the file path to the helper, so the raw service-account JSON is not injected into the shell process table.
  7. The module publishes the same contract consumed by:
  8. core/onprem/vyos-template-seed
  9. core/hetzner/vyos-image-seed

The packaged examples call the helpers through:

  • ${HYOPS_CORE_ROOT:-$HOME/.hybridops/core/app}/tools/build/vyos/...

so the same module inputs work from a source checkout and from the installed tarball payload.

Downstream blueprints then consume:

  • artifact_state_ref: core/shared/vyos-image-build#<instance>
  • artifact_key: vyos-1.5

Fresh-user prerequisites:

  1. Provision one object repository for image publishing, for example:
  2. org/gcp/object-repo#vyos_artifacts
  3. Store one upload credential outside Terraform state, for example:
  4. HYOPS_VYOS_GCS_SA_JSON
  5. If runner-based publishing is required, persist that credential into the selected external secret authority or runtime vault cache before dispatch.

Fresh-user first-run path:

  1. Apply the object repository module.
  2. Store the upload credential in the env runtime vault or external secret source.
  3. Apply core/shared/vyos-image-build.
  4. Consume the published artifact state from:
  5. core/onprem/vyos-template-seed
  6. core/hetzner/vyos-image-seed

Notes:

  • prefer a pinned, mirrored artifact URL over upstream latest
  • keep the official ISO URL in source_iso_url for provenance
  • prefer repo_state_ref over hardcoding bucket/container names in the build inputs
  • explicit image_source_url in downstream seed modules remains the override path, not the default
  • default ISO build method is now vyos-vm-images (official upstream path used by HybridOps unless explicitly overridden)
  • vyos-vm-images builder requirements:
  • Linux builder host (Debian/Ubuntu baseline)
  • passwordless sudo for package and image tooling
  • MUST NOT run on a Proxmox hypervisor host directly
  • sufficient free disk for ISO + intermediate image artifacts
  • recommended pattern:
  • run core/shared/vyos-image-build on a dedicated build runner
  • publish the artifact once
  • consume state-first from core/onprem/vyos-template-seed and core/hetzner/vyos-image-seed
  • set HYOPS_VYOS_ISO_BUILD_METHOD=packer only when you intentionally need the packaged two-stage Packer fallback:
export HYOPS_VYOS_PACKER_TEMPLATE="${HYOPS_CORE_ROOT:-$HOME/.hybridops/core/app}/packs/images/packer/shared/qemu/images/10-vyos-image-build@v1.0/stack/vyos-qemu.pkr.hcl"
  • the packaged Packer scaffold defaults qemu_accelerator = "kvm"
  • expected Packer builder: dedicated host that exposes /dev/kvm
  • the wrapper fails fast if the ISO build is attempted on tcg, unless you explicitly opt into debug mode with HYOPS_VYOS_ALLOW_TCG=1
  • the ISO download is cached on the builder under ${XDG_CACHE_HOME:-$HOME/.cache}/hybridops/vyos by default so reruns do not redownload the full image each job
  • the packaged Packer vars scaffold performs:
  • stage 1: console-driven install image from the live ISO
  • stage 2: console bootstrap of DHCP plus SSH on the installed disk, install and enable cloud-init plus qemu-guest-agent, then SSH plus final template sanitation
  • validate and adjust the Packer stage-1 install prompt timing/order for the exact VyOS build you pin
  • the packaged KVM wait profile is now tuned for a normal /dev/kvm builder, not for a tcg debug host; if your pinned VyOS build still needs more time, adjust the vars scaffold instead of accepting huge default waits
  • the packaged stage-1 template also supports serial_device; set it to a file path while debugging installer behavior if VNC timing is unclear
  • the packaged stage-1 template also supports monitor_device; set it to a unix socket and capture screenshots with screendump when you need to confirm what the KVM/VNC console is actually showing
  • the installed-disk stage now assumes a KVM-backed builder with moderate waits; tune installed_boot_wait and installed_boot_command only if the pinned VyOS build proves it needs more time

  • the stage-1 template must declare:

  • source_iso_path
  • build_output_directory
  • the stage-2 template must declare:
  • source_disk_path
  • build_output_directory
  • the wrapper then normalizes the validated stage-2 disk into the requested artifact_local_path
  • the packaged vars file is auto-loaded by default and is still a starting-point scaffold that may need refinement per pinned VyOS release
  • the Packer wrapper preserves the stage-1 disk on failure (packer build -on-error=abort) so installer/reboot mismatches can be inspected on the builder host
  • the packaged stage-1 scaffold explicitly chooses the KVM console during install image, because the stage-2 bootstrap path uses the installed disk over VNC/KVM before switching to SSH
  • if you do not want to use Packer, HYOPS_VYOS_ISO_BUILD_COMMAND is still supported as an explicit override
  • if you want a different cache location on the builder, set HYOPS_VYOS_ISO_CACHE_DIR
  • a fresh HyOps user can run the build-and-publish path once they have:
  • an object repo state such as org/gcp/object-repo#vyos_artifacts
  • an upload credential outside Terraform state, supplied as HYOPS_VYOS_GCS_SA_JSON
  • without the upload credential, the module still builds locally but intentionally fails before claiming the artifact is published

Current packaged Packer stage behavior:

  1. boot the live VyOS ISO
  2. run the documented install image flow through console automation
  3. reassert the console login prompt, then follow the installer's reboot prompt
  4. boot the installed disk, recover the console login prompt, enable DHCP and SSH on the console, then let Packer connect over SSH
  5. install and enable cloud-init plus qemu-guest-agent so Proxmox clone-time ciuser/ipconfig/cicustom data is consumed after first boot
  6. clean cloud-init state and remove builder-specific ethernet config so the resulting image is template-safe
  7. fail loudly if the build cannot produce a real Proxmox cloud image

Treat the packaged prompt timings as release-specific scaffolding, not as something guaranteed for every rolling build.