Provision Hetzner VyOS Edge (HyOps Blueprint)¶
Use the shipped blueprint ref networking/hetzner-vyos-edge@v1 to build/publish (or reuse) a canonical VyOS artifact, 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 one canonical versioned
qcow2throughcore/shared/vyos-image-build - let
core/hetzner/vyos-image-seedconsume that shared artifact contract - when the shared artifact is private GCS-backed, declare
HYOPS_VYOS_GCS_SA_JSON(orHYOPS_VYOS_GCS_SA_JSON_FILE) inrequired_env - let the built-in Hetzner wrapper convert and expose the temporary raw import artifact
- let
org/hetzner/vyos-edge-foundationconsumeimage_state_ref
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.
Rerun safety:
- The shared-network and edge-foundation steps now verify live Hetzner state before skipping on
state-ok. - If the published edge server ids are missing from the Hetzner API,
deployreruns the foundation step instead of trusting stale state.
Inputs¶
The blueprint is state-first where possible:
core/shared/vyos-image-buildpublishes the canonical VyOS artifact URL contractcore/hetzner/vyos-image-seedpublishes the custom Hetzner image referenceorg/hetzner/shared-private-network#shared_networkpublishes the reusable Hetzner private network contractorg/hetzner/vyos-edge-foundationconsumes it byimage_state_ref
Operator-supplied values still required:
- object repo state or explicit artifact URL for the build step
- a public wrapper base URL reachable from Hetzner rescue when using the qcow2 wrapper path
- SSH public key when HyOps must create the Hetzner SSH key
- explicit
ssh_source_cidrsandipsec_source_cidrsfor the live peer set
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- Replace all
CHANGE_ME_*values before preflight or deploy. - Set at minimum:
CHANGE_ME_HETZNER_NETWORK_ZONECHANGE_ME_HETZNER_PRIVATE_NETWORK_NAMECHANGE_ME_HETZNER_PRIVATE_NETWORK_CIDRCHANGE_ME_HETZNER_LOCATIONCHANGE_ME_HETZNER_HOME_LOCATIONCHANGE_ME_HETZNER_SERVER_TYPECHANGE_ME_HETZNER_SSH_KEY_NAMECHANGE_ME_EDGE_FIREWALL_NAMECHANGE_ME_EDGE_FLOATING_IP_NAMECHANGE_ME_EDGE01_PRIVATE_IPCHANGE_ME_EDGE02_PRIVATE_IP- 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_artifact_build.inputs.artifact_urlis set, HyOps uses it directly. - If
vyos_artifact_build.inputs.artifact_urlis empty, HyOps runs build/publish and usesrepo_state_refto discover bucket backend. vyos_imageconsumes the resulting shared artifact state by default.- The shipped blueprint now provisions or reuses
org/hetzner/shared-private-network#shared_networkbefore the edge foundation step. - The default routed-edge contract now uses
foundation_state_ref: org/hetzner/shared-private-network#shared_network. - The default Hetzner path is now state-first: consume
artifact_state_ref: core/shared/vyos-image-build#vyos_default_buildand let the built-in wrapper handle the qcow2 import path. - When that shared artifact is private GCS-backed, declare
HYOPS_VYOS_GCS_SA_JSONinvyos_image.inputs.required_env. - The execution host for the wrapper path must have
qemu-imgand must be able to expose the wrapped artifact through a public base URL. - Override
foundation_state_ref,private_network_name, orprivate_network_cidronly when you intentionally need a different network ownership model. - Set
ssh_source_cidrsandipsec_source_cidrsexplicitly so reapply does not widen firewall rules or drift into0.0.0.0/0defaults. - 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 when the wrapper preconditions are satisfied. Use a direct
raw.xzimport URL only when you intentionally want to bypass the wrapper.
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.