# Migrate from Hetzner Cloud Networks to Quake AI

Source: https://docs.quake.ai/docs/network/migration/migrate-from-hetzner-networks
Markdown: https://docs.quake.ai/docs/network/migration/migrate-from-hetzner-networks.md

---

# Migrate from Hetzner Cloud Networks to Quake AI

Hetzner Cloud's private networking, firewall, and floating IP models map closely to Quake AI's [OpenStack Neutron](/resources/migration/openstack). The primary structural addition on Quake AI is the **explicit router** object: Hetzner handles internet routing implicitly, while Neutron requires you to create a router and attach your subnet to it. Neutron's security group references (`--remote-group`) also provide a more precise alternative to Hetzner's CIDR-based inter-tier rules.

## Service mapping

<MigrationTable provider="hetzner" service="network" />


## Prerequisites

- A Quake AI account with [application credentials](/docs/tools/generate-app-credentials)
- The [OpenStack CLI](/docs/tools/install-openstack-client) installed and configured
- An inventory of your Hetzner resources: Networks, Subnets, Cloud Firewalls, Floating IPs, Load Balancers, and DNS zones
- An SSH key pair imported to Quake AI (`openstack keypair create --public-key`)

## Topology mapping

The mapping is close between Hetzner and Neutron. The main structural difference is the explicit router object required on Quake AI.

<Figure caption="Hetzner Network with subnets, Cloud Firewalls, and Floating IPs maps to a Neutron network with router, floating IPs, and security groups">

```d2
direction: down

hetzner: Hetzner Network {
  subnet: Subnet
  server: Server
  primary_ip: Primary IP
  fip: Floating IP
  cloud_fw: Cloud Firewall
  server_label: Server Label
  subnet -> server
  primary_ip -> server
  fip -> server
  server_label -> server
  cloud_fw -> server_label: label-based
}

neutron: Quake AI Neutron {
  network: Tenant Network
  subnet: Subnet
  router: Router
  port: Port
  sg: Security Group
  fip: Floating IP
  network -> subnet
  router -> network
  port -> network
  sg -> port: port-level
  fip -> port
}

hetzner -> neutron: maps to
```

</Figure>

| Hetzner concept | Neutron equivalent | Notes |
|---|---|---|
| Network (hcloud Network) | Network | Direct match |
| Subnet (hcloud Subnet) | Subnet | Direct match |
| Primary IP (public IPv4/IPv6) | PublicEphemeral model or floating IP | Primary IPs persist on rescale; floating IPs are separate objects |
| Floating IP | Floating IP | Direct match; implementation differs (see below) |
| Cloud Firewall | Security Group | Stateful, allow-only, applied to servers/labels and ports |
| Server label | Security Group assignment | Labels target firewalls; SGs assign to ports |
| Load Balancer | Self-managed reverse proxy or external edge | Feature comparison below |
| vSwitch (dedicated servers) | **No equivalent** | Hetzner vSwitch for dedicated servers has no Neutron equivalent |
| No router concept | Router | Hetzner routes implicitly; Neutron requires explicit router creation |

### Set up the Neutron equivalent

```bash
openstack network create my-network

openstack subnet create my-subnet \
  --network my-network \
  --subnet-range 10.0.0.0/24 \
  --gateway 10.0.0.1 \
  --dns-nameserver 8.8.8.8

openstack router create my-router
openstack router set my-router --external-gateway PublicStatic
openstack router add subnet my-router my-subnet
```

On Hetzner, you create a Network and Subnet, then attach servers. On Quake AI, you add the explicit router step. This router handles both outbound SNAT and inbound DNAT (via floating IPs).

## Security rule translation

Hetzner Cloud Firewalls and Neutron security groups share the same fundamental model.

| Dimension | Hetzner Cloud Firewall | Neutron Security Group |
|---|---|---|
| Statefulness | Stateful | Stateful |
| Rule model | Allow-only | Allow-only |
| Inbound default | Deny-all | Deny-all |
| Outbound default | Allow-all | Allow-all |
| Applied to | Server or label group | Port |
| Source types | CIDR only | CIDR and Security Group ID |

The notable improvement: Hetzner firewalls can only reference source IPs by CIDR. Neutron security groups support `--remote-group` references, enabling more precise inter-tier rules that follow instances regardless of IP address changes.

### 3-tier app example

**Hetzner source:**
- `fw-web`: inbound TCP 80/443 from `0.0.0.0/0`; inbound TCP 22 from admin CIDR
- `fw-app`: inbound TCP 8080 from `10.0.0.0/24` (web-tier subnet CIDR)
- `fw-db`: inbound TCP 5432 from `10.0.0.0/24` (app-tier subnet or specific IPs)

**Neutron target (upgraded to security group references):**

```bash
openstack security group create sg-web
openstack security group rule create sg-web \
  --protocol tcp --dst-port 80 --remote-ip 0.0.0.0/0 --ingress
openstack security group rule create sg-web \
  --protocol tcp --dst-port 443 --remote-ip 0.0.0.0/0 --ingress
openstack security group rule create sg-web \
  --protocol tcp --dst-port 22 --remote-ip ADMIN_CIDR --ingress

openstack security group create sg-app
openstack security group rule create sg-app \
  --protocol tcp --dst-port 8080 --remote-group sg-web --ingress

openstack security group create sg-db
openstack security group rule create sg-db \
  --protocol tcp --dst-port 5432 --remote-group sg-app --ingress
```



The Hetzner approach of using a subnet CIDR (`10.0.0.0/24`) as the app tier source is broad: it allows any server in that subnet to reach the database. The Neutron approach using `--remote-group sg-app` restricts access to servers with `sg-app` applied, regardless of IP address. This is a security posture improvement over your Hetzner configuration.



## Load balancer migration

Replace a Hetzner Load Balancer with a reverse proxy such as HAProxy, Nginx, Caddy, Traefik, or Envoy. Assign a floating IP to the proxy instance and route requests to application instances over a private network.

Configure forwarding, health checks, sticky sessions, redirects, and Proxy Protocol in the proxy. Use Certbot or Caddy for certificate issuance and renewal. Put an external CDN or WAF in front of the proxy when you need an edge service.

## Floating IP setup

Hetzner Floating IPs are the closest conceptual match to Neutron Floating IPs of all five providers.

| Hetzner Floating IP | Neutron Floating IP |
|---|---|
| Static public IPv4 or IPv6 | Static public IPv4 (IPv6 not documented on Quake AI) |
| Re-assignable within network zone (eu-central alone spans the Frankfurt, Nuremberg, and Helsinki datacenter locations, a wider scope than a single Quake AI region) | Re-assignable within region |
| Charged monthly | Included in Quake AI pricing |
| Requires manual OS-level configuration | Assigned automatically via router NAT |
| Up to 10 per account (default) | Operator-configured limits |

The key implementation difference: Hetzner Floating IPs require manual OS-level configuration (adding the IP as an alias on the network interface) and the config does not survive reboot without persistent setup. Neutron Floating IPs work via DNAT on the router. The instance OS sees only its private IP; no OS configuration is needed.

```bash
openstack floating ip create PublicStatic
openstack server add floating ip MY_INSTANCE FLOATING_IP_ADDRESS
```

## DNS cutover

Hetzner provides a managed DNS console. Migrate your zones to an external provider.

1. **Export zone file**: From Hetzner DNS Console, export the zone as a BIND-format zone file.
2. **Clean up TTL mismatches**: Hetzner DNS requires that records with the same name and type have identical TTLs. Resolve any inconsistencies before exporting.
3. **Lower TTLs**: Set all records to 300 seconds; wait for the current TTL period to expire.
4. **Import at new provider**: Upload the zone file or use Terraform with the DNS provider.
5. **Validate**: `dig @NEW_NAMESERVER example.com A`
6. **Update registrar NS records**.
7. **Monitor for 48 hours** and restore TTLs after successful cutover.

## Validation checklist

- [ ] Neutron network, subnet, and router are operational (router is the key addition vs. Hetzner)
- [ ] Security group rules match your Cloud Firewall rules
- [ ] Label-based firewall groups are replaced by security group assignments on the correct ports
- [ ] CIDR-based inter-tier rules have been upgraded to security group references where appropriate
- [ ] Floating IPs are associated with the correct instance ports (no OS-level config needed)
- [ ] Reverse proxy health checks pass for application backends
- [ ] TLS renewal automation is in place (certbot or cert-manager)
- [ ] DNS records resolve to the proxy floating IP or external edge hostname
- [ ] Applications respond correctly through the full network path

## Provider-specific gotchas

| Topic | Detail |
|---|---|
| Bandwidth model | Hetzner includes a monthly transfer allowance that differs between EU and US locations, with per-GB overage. Quake AI includes bandwidth in flavor pricing. For Hetzner workloads within the included allowance, the shift is bandwidth-neutral. See [Hetzner pricing](https://www.hetzner.com/cloud). |
| No router concept | Hetzner handles routing implicitly. Creating a Neutron router and attaching the subnet is a required explicit step with no Hetzner analog. |
| vSwitch / dedicated servers | Hetzner vSwitch connects Cloud servers to dedicated root servers via private L2 links. No Quake AI equivalent. Dedicated server workloads must migrate to cloud instances. |
| Firewall label targeting | Hetzner applies firewalls to servers by label. Neutron assigns SGs per-port. At scale, use Terraform's `openstack_networking_port_v2` resource for declarative assignment. |
| Floating IP OS behavior | On Hetzner, Floating IPs require manual OS config. On Quake AI, Floating IPs are handled transparently by router NAT. No OS configuration needed. |

## See also

- [Migrating from Hetzner Cloud to Quake AI](/resources/migration/from-hetzner): full cross-service migration hub
- [Migrate from Hetzner Cloud Servers](/docs/compute/migration/migrate-from-hetzner-servers): compute workload migration
- [Network migration guides](/docs/network/migration): all provider guides
- [Create a router](/docs/network/how-to/create-router): the key Neutron object Hetzner does not have
