11# Fix Hetzner private-network readiness
22
3- Status: needs-triage
3+ Status: closed
44Type: AFK
55
66## Parent
@@ -25,22 +25,52 @@ The public IPv4 path worked and produced valid benchmark JSONL.
2525
2626## Acceptance criteria
2727
28- - [ ] After ` terraform apply ` , both nodes expose their configured private IPs
28+ - [x ] After ` terraform apply ` , both nodes expose their configured private IPs
2929 on an UP interface.
30- - [ ] A smoke check proves client-to-server ICMP and TCP connectivity over the
30+ - [x ] A smoke check proves client-to-server ICMP and TCP connectivity over the
3131 private IPs before benchmark traffic starts.
32- - [ ] The Hetzner README documents the private-path readiness check.
33- - [ ] If explicit OS network configuration is needed, it is handled by
32+ - [x ] The Hetzner README documents the private-path readiness check.
33+ - [x ] If explicit OS network configuration is needed, it is handled by
3434 Terraform/cloud-init without making cloud-init large or fragile.
35- - [ ] If private paths are intentionally deferred, the README and outputs make
36- that limitation clear.
35+ - [x] If private paths are intentionally deferred, the README and outputs make
36+ that limitation clear. Not applicable: private paths are supported after
37+ the readiness check passes.
3738
3839## Blocked by
3940
4041None.
4142
43+ ## Resolution
44+
45+ Implemented private-network readiness as a first-class Hetzner operator step:
46+
47+ - Cloud-init writes a small static netplan file for the first Hetzner private
48+ NIC when private networking is enabled.
49+ - The private NIC defaults to ` enp7s0 ` , uses the Terraform-assigned private IP
50+ as ` /32 ` , MTU 1450, and routes the private network CIDR via the subnet
51+ gateway.
52+ - Cloud-init stops and masks ` hc-net-ifup@enp7s0.service ` , flushes any early
53+ global address on the private NIC, then applies netplan.
54+ - ` just bench-transport-private-check ` waits for cloud-init on both nodes,
55+ confirms peer routes, pings the server private IP from the client, and runs a
56+ one-second TCP ` iperf3 ` probe over the private IP.
57+ - Terraform outputs now include ` private_network_check_command ` so operators
58+ can discover the required readiness probe from the applied run.
59+
4260## Comments
4361
4462- 2026-05-20: Created from Hetzner smoke ` 20260520T134420Z-smoke ` . Public IPv4
4563 benchmark traffic is usable; private-network benchmark traffic is not yet a
4664 reliable operator path.
65+ - 2026-05-21: Implementation started. Direction: configure the first Hetzner
66+ private NIC explicitly in cloud-init using static netplan and add a
67+ ` just bench-transport-private-check ` readiness probe that proves peer route,
68+ ICMP, and TCP connectivity before private-path benchmarks.
69+ - 2026-05-21: Closed after Hetzner ARM smoke
70+ ` 20260521T093427Z-private-smoke ` . The client and server both exposed
71+ ` enp7s0 ` as UP with ` 10.88.0.11/32 ` and ` 10.88.0.12/32 ` , respectively, and
72+ routes to the peer private IPs via ` 10.88.0.1 ` . The readiness check proved
73+ client-to-server ICMP with 3/3 packets delivered and TCP with
74+ ` iperf3 --client 10.88.0.12 --port 55209 --time 1 ` . The Terraform pair was
75+ destroyed afterward, and ` just bench-transport-verify-clean ` confirmed no
76+ Terraform state entries or labelled Hetzner resources remained.
0 commit comments