Provision Hetzner VyOS Edge (HyOps Blueprint)¶
Purpose: Build or discover the canonical VyOS image record, seed the Hetzner image, and provision the default routed edge pair.
Owner: Network/platform engineering
Trigger: New Hetzner edge bring-up, image refresh, or routed edge rebuild
Impact: Creates or refreshes the public VyOS edge pair that fronts Site-A and feeds the WAN control plane
Severity: P2
Pre-reqs: Hetzner init is ready for the target env, the canonical image record path is reachable, and the operator provides a valid SSH public key.
Rollback strategy: Destroy the edge foundation state and reseed/reapply with corrected image or key inputs.
Use the shipped blueprint ref networking/hetzner-vyos-edge@v1 to build/publish (or reuse) a canonical VyOS record, seed or discover the Hetzner image, and provision the default routed Hetzner edge pair.
This is the target-state replacement for the Linux strongSwan/FRR edge path. The shared Hetzner control host remains a separate Linux service host.
Current recommended image path:
- publish a versioned public
qcow2for Proxmox consumption - publish a versioned public
raw.xzfor Hetzner consumption - seed the Hetzner image from that direct
raw.xz - let
org/hetzner/vyos-edge-foundationconsumeimage_state_ref
Related¶
Related reading¶
- VyOS as Cost-Effective Edge Router
- Full Mesh Topology for High Availability
- Network routing contract
- Deploy Edge Control Plane (HyOps Blueprint)
- Extend On-Prem Into Hetzner Site-A (HyOps Blueprint)
- Operate Shared VyOS Image Build Pipeline (HyOps)
Important first-boot behavior:
- Hetzner VyOS custom images now perform one intentional first-boot reboot after cloud-init writes the final
config.boot. - Treat the first boot as image customization and the second boot as the point where routed public/private networking becomes active.
- Do not treat a short initial SSH gap as image failure unless the node is still unreachable after that reboot window.
- Hetzner Cloud Networks are routed. The edge private NIC is therefore configured as
private_ip/32, with an explicit route toprivate_network_cidrvia the standard network gateway (cidrhost(private_network_cidr, 1)), not as an on-link/24.
Inputs¶
The blueprint is state-first where possible:
core/shared/vyos-image-buildpublishes the canonical VyOS record URL contractcore/hetzner/vyos-image-seedpublishes the custom Hetzner image referenceorg/hetzner/vyos-edge-foundationconsumes it byimage_state_ref
Operator-supplied values still required:
- object repo state or explicit record URL for the build step
- SSH public key
Initialize an env-scoped overlay¶
hyops blueprint init --env dev \
--ref networking/hetzner-vyos-edge@v1 \
--dest-name hetzner-vyos-edge.yml
Edit:
~/.hybridops/envs/dev/config/blueprints/hetzner-vyos-edge.yml- If you already have a seeded Hetzner custom image, set
image_ref. - The blueprint now defaults to
core/shared/vyos-image-build#vyos_default_build. - If
vyos_record_build.inputs.record_urlis set, HyOps uses it directly. - If
vyos_record_build.inputs.record_urlis empty, HyOps runs build/publish and usesrepo_state_refto discover bucket backend. vyos_imageconsumes the resulting shared record state by default.- For the clean Hetzner path, prefer setting
image_source_urlto a direct publicraw.xzrecord. - The qcow2 auto-wrap path remains supported only when the execution host has
qemu-imgand can expose the wrapped record through a public base URL. - If your only upstream source is an installer ISO, leave
image_source_urlempty and provide a customseed_commandthat performs the ISO-to-image workflow before snapshot creation. - Leave
seed_tool: hcloud-upload-imageunless you provide a customseed_command. - HyOps fails fast when
image_source_urlis invalid/unreachable, with guidance to runcore/shared/vyos-image-build. - A single operator-managed qcow2 URL can still serve both Proxmox and Hetzner, but only when the wrapper preconditions are satisfied. Treat direct
raw.xzimport as the primary Hetzner path.
If hyops blueprint init --ref networking/hetzner-vyos-edge@v1 says the blueprint is not found under
~/.hybridops/core/app/blueprints/..., your installed HyOps payload is older than the current source tree.
Refresh the install, or use the repo-local CLI until the installed payload is updated.
Validate¶
hyops blueprint preflight --env dev \
--file "$HOME/.hybridops/envs/dev/config/blueprints/hetzner-vyos-edge.yml"
Deploy¶
hyops blueprint deploy --env dev \
--file "$HOME/.hybridops/envs/dev/config/blueprints/hetzner-vyos-edge.yml" \
--execute
Verify¶
jq '.status,.outputs.image_ref,.outputs.image_description' \
"$HOME/.hybridops/envs/dev/state/modules/core__hetzner__vyos-image-seed/latest.json"
jq '.status,.outputs.edge01_public_ip,.outputs.edge02_public_ip' \
"$HOME/.hybridops/envs/dev/state/modules/org__hetzner__vyos-edge-foundation/latest.json"
EDGE_A_IP="$(jq -r '.outputs.edge01_public_ip' "$HOME/.hybridops/envs/dev/state/modules/org__hetzner__vyos-edge-foundation/latest.json")"
EDGE_B_IP="$(jq -r '.outputs.edge02_public_ip' "$HOME/.hybridops/envs/dev/state/modules/org__hetzner__vyos-edge-foundation/latest.json")"
ssh -o StrictHostKeyChecking=no "vyos@${EDGE_A_IP}" 'echo HYOPS_HETZNER_EDGE_A_OK'
ssh -o StrictHostKeyChecking=no "vyos@${EDGE_B_IP}" 'echo HYOPS_HETZNER_EDGE_B_OK'
If the edge foundation is reapplied and Hetzner assigns new public IPs, refresh
org/gcp/wan-vpn-to-edge before rerunning WAN day-2. The cloud VPN peer IPs
must track the current org/hetzner/vyos-edge-foundation state.