Hetzner: cpx (new gen) defaults + capacity-aware placement#166
Open
barnabasbusa wants to merge 5 commits intomasterfrom
Open
Hetzner: cpx (new gen) defaults + capacity-aware placement#166barnabasbusa wants to merge 5 commits intomasterfrom
barnabasbusa wants to merge 5 commits intomasterfrom
Conversation
ARM cax* capacity at Hetzner has been chronically tight across all EU locations, causing repeated `resource_unavailable` placement failures on apply. Switch the supernode/fullnode defaults to the spec-equivalent AMD shared-vCPU sizes which have far better availability: - supernode: cax41 (16/32) -> cpx51 (16/32) - fullnode: cax31 (8/16) -> cpx41 (8/16) The arch label logic already keys off the `^cax` regex, so labels will automatically flip to `arch:amd64`.
Hetzner is rolling out a new CX line that replaces the CPX series in many locations. CPX SKUs (cpx41/cpx51) are no longer creatable in fsn1/nbg1/hel1, returning `unsupported location for server type (invalid_input)` from the API. Switch defaults to the new CX equivalents at identical specs and slightly lower price: - supernode: cpx51 (16/32) -> cx53 (16/32) — €31.99 -> €22.99 - fullnode: cpx41 (8/16) -> cx43 (8/16) — €24.49 -> €12.49
Hetzner ARM (cax*) capacity has been chronically tight in EU and
the legacy CPX line (cpx41/cpx51) is no longer creatable in some
regions. Newer cpx42/cpx62 are widely available and still ~3-4x
cheaper than DigitalOcean for equivalent specs.
Two behavior changes layered together:
1. Default sizes flipped to the new-gen CPX:
- supernode: cpx62 (16 vCPU / 32 GB / 640 GB)
- fullnode: cpx42 (8 vCPU / 16 GB / 320 GB)
2. Capacity-aware placement: query `hcloud_datacenters` and
`hcloud_server_type` data sources at plan time, build the set
of locations whose datacenters currently report both SKUs as
`available`, and round-robin only across those. Falls back to
the full region list if every region is sold out.
- `lifecycle { ignore_changes = [location] }` keeps existing
servers pinned where they were placed even if next plan's
filter would prefer a different region (location is
replacement-forced otherwise).
- `hcloud_server_network` reads the actual server location
post-state so the network reference stays correct after any
drift between planned and real location.
Arch labels still flip to `arch:amd64` automatically via the
existing `^cax` regex.
Capture why we landed on cpx42/cpx62 (capacity vs cax/legacy cpx, cost vs DigitalOcean) so future operators don't have to relitigate the choice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two changes layered together to address recurring
resource_unavailableandunsupported location for server typeerrors onterraform apply:1. New default SKUs
cax41(16 ARM / 32 GB / 320 GB)cpx62(16 AMD / 32 GB / 640 GB)cax31(8 ARM / 16 GB / 160 GB)cpx42(8 AMD / 16 GB / 320 GB)Hetzner ARM
cax*capacity has been chronically tight, and the legacycpx41/cpx51SKUs are no longer creatable in some EU locations. The new-gencpx42/cpx62are widely available.Cost vs DigitalOcean
cpx*is more expensive thancax*/cx*, but still dramatically cheaper than DigitalOcean for equivalent specs:cpx42≈ €25/mos-8vcpu-16gb≈ €88/mo (~$96)cpx62≈ €50/mos-16vcpu-32gb≈ €177/mo (~$192)So we're roughly 3–4× cheaper than DO while staying on a SKU that's actually in stock. For a multi-month devnet that's hundreds of euros saved per supernode.
The arch label logic at
hetzner.tfalready keys off the^caxregex, so labels automatically flip toarch:amd64.2. Capacity-aware placement
At every plan/apply, query
hcloud_datacentersandhcloud_server_typedata sources, build the set of locations whose datacenters currently report both SKUs asavailable, and round-robin new servers only across those. Falls back to the fullvar.hetzner_regionslist if every region is sold out (so plan doesn't error out — at that point you're stuck either way).lifecycle { ignore_changes = [location] }onhcloud_serverkeeps existing placements pinned even if next plan's filter would prefer a different region (location is replacement-forced onhcloud_serverotherwise).hcloud_server_networknow readshcloud_server.main[each.key].location(the actual post-state location) so the network reference stays correct under any drift.Test plan
resource_unavailable/unsupported locationerrorsecho 'local.hetzner_available_locations' | terraform consolereturns the expected non-empty list when capacity is healthy