Neu: PostScale -- E-Mail-API für transaktionale, eingehende und maskierte Adressen. PostScale

    Multi-Provider-DNS mit Terraform & DNSControl

    DNS-Zonen über DNScale und Hetzner DNS für Redundanz bereitstellen — mit Terraform oder DNSControl.

    Wenn Sie Ihr DNS über einen einzigen Anbieter betreiben, haben Sie einen Single Point of Failure. Fällt dieser Anbieter aus — sei es durch einen Ausfall, einen DDoS-Angriff oder eine Fehlkonfiguration — werden Ihre Domains unerreichbar. Multi-Provider-DNS eliminiert dieses Risiko, indem dieselbe Zone gleichzeitig von zwei unabhängigen Anbietern bedient wird.

    Dieser Leitfaden zeigt die Einrichtung von DNScale und Hetzner DNS als Dual-Provider mit Terraform oder DNSControl. Beide Tools ermöglichen es, Einträge einmal zu definieren und an beide Anbieter zu pushen, wobei alles synchron bleibt — ohne manuelle Duplizierung.

    Warum Multi-Provider-DNS

    DNS ist das Fundament jedes Internet-Dienstes, den Sie betreiben. Ein Provider-Ausfall bedeutet nicht nur, dass Ihre Website unerreichbar ist — E-Mails fließen nicht mehr, APIs werden unzugänglich, und Dienste, die auf SRV- oder TXT-Einträge angewiesen sind, brechen zusammen.

    Multi-Provider-DNS funktioniert, indem Ihre Domain an Nameserver beider Anbieter delegiert wird. Resolver weltweit fragen denjenigen Satz von Nameservern ab, der antwortet. Ist ein Anbieter ausgefallen, liefert der andere weiterhin Antworten.

    Wann macht Multi-Provider Sinn?

    • Produktionsdomains, bei denen Ausfallzeiten echte Kosten verursachen
    • Compliance-Umgebungen, die Redundanz erfordern
    • Globale Dienste, bei denen die Anbieterabdeckung je nach Region variiert

    Wann ist es übertrieben? Für Entwicklungsdomains, internes Tooling oder Domains, bei denen einige Minuten Ausfallzeit akzeptabel sind, reicht ein einzelner Anbieter mit guter Verfügbarkeit in der Regel aus.

    Wie es funktioniert

    Das Konzept ist unkompliziert:

    1. Einträge einmal definieren in Terraform oder DNSControl
    2. Identische Einträge pushen an sowohl DNScale als auch Hetzner DNS
    3. NS-Einträge beim Registrar setzen, die auf Nameserver beider Anbieter verweisen
    4. Resolver fragen einen der Anbieter ab — wer zuerst antwortet, gewinnt
    ┌──────────────┐
    │   Registrar  │
    │              │
    NS-Einträge: │
    │  ns1.dnscale │
    │  ns2.dnscale │
    │  hydrogen.ns │  ← Hetzner
    │  oxygen.ns   │  ← Hetzner
    └──────┬───────┘
    
    
    ┌──────────────┐     ┌──────────────┐
    │   DNScale    │     │  Hetzner DNS
    │              │     │              │
    │ example.com  │     │ example.com  │
    A, MX, TXT  │     │  A, MX, TXT
    │ (identisch)  │     │ (identisch)  │
    └──────────────┘     └──────────────┘
           ▲                    ▲
           │    ┌──────────┐    │
           └────│ Resolver │────┘
                └──────────┘
            Fragt einen von beiden ab

    Beide Anbieter halten dieselben Einträge. Ihr IaC-Tool ist die einzige Quelle der Wahrheit, und beide Anbieter sind lediglich Spiegel dieser Wahrheit.

    Voraussetzungen

    Sie benötigen:

    1. Ein DNScale-Konto mit einem API-Schlüssel — API-Schlüssel erhalten
    2. Ein Hetzner DNS-Konto mit einem API-Token — Hetzner DNS Console
    3. Terraform (v1.0+) oder DNSControl (v4.0+) installiert
    4. Eine Domain unter Ihrer Kontrolle mit Zugang zur NS-Konfiguration beim Registrar

    Terraform: Multi-Provider-Setup

    Terraform macht Multi-Provider-DNS übersichtlich durch native Unterstützung mehrerer Provider und for_each-Schleifen. Sie definieren Ihre Einträge einmal in einem locals-Block und erstellen sie bei beiden Anbietern.

    Provider-Konfiguration

    # providers.tf
    terraform {
      required_providers {
        dnscale = {
          source  = "dnscaleou/dnscale"
          version = "~> 1.0"
        }
        hetznerdns = {
          source  = "timohirt/hetznerdns"
          version = "~> 2.2"
        }
      }
    }
     
    provider "dnscale" {
      api_key = var.dnscale_api_key
    }
     
    provider "hetznerdns" {
      apitoken = var.hetzner_dns_token
    }
    # variables.tf
    variable "dnscale_api_key" {
      description = "DNScale API key"
      type        = string
      sensitive   = true
    }
     
    variable "hetzner_dns_token" {
      description = "Hetzner DNS API token"
      type        = string
      sensitive   = true
    }
     
    variable "domain" {
      description = "Domain to manage"
      type        = string
      default     = "example.com"
    }

    Einträge einmal definieren

    Der Schlüssel zu Multi-Provider-DNS mit Terraform ist die Definition der Einträge an einer einzigen Stelle. Verwenden Sie locals, um ein gemeinsames Record-Set zu erstellen:

    # records.tf
    locals {
      dns_records = {
        # A-Einträge
        "root-a" = {
          name  = "@"
          type  = "A"
          value = "203.0.113.10"
          ttl   = 3600
        }
        "www-a" = {
          name  = "www"
          type  = "CNAME"
          value = "example.com."
          ttl   = 3600
        }
        # Mail
        "mx-primary" = {
          name     = "@"
          type     = "MX"
          value    = "mail.example.com."
          ttl      = 3600
          priority = 10
        }
        "mail-a" = {
          name  = "mail"
          type  = "A"
          value = "203.0.113.20"
          ttl   = 3600
        }
        # SPF
        "spf" = {
          name  = "@"
          type  = "TXT"
          value = "v=spf1 mx -all"
          ttl   = 3600
        }
        # IPv6
        "root-aaaa" = {
          name  = "@"
          type  = "AAAA"
          value = "2001:db8::1"
          ttl   = 3600
        }
      }
    }

    Bei beiden Anbietern erstellen

    # dnscale.tf
    resource "dnscale_zone" "primary" {
      name = var.domain
    }
     
    resource "dnscale_record" "all" {
      for_each = local.dns_records
     
      zone_id  = dnscale_zone.primary.id
      name     = each.value.name
      type     = each.value.type
      content  = each.value.value
      ttl      = each.value.ttl
      priority = lookup(each.value, "priority", null)
    }
    # hetzner.tf
    resource "hetznerdns_zone" "secondary" {
      name = var.domain
      ttl  = 3600
    }
     
    resource "hetznerdns_record" "all" {
      for_each = local.dns_records
     
      zone_id = hetznerdns_zone.secondary.id
      name    = each.value.name
      type    = each.value.type
      value   = each.value.value
      ttl     = each.value.ttl
    }

    Für MX-Einträge bei Hetzner DNS wird die Priorität typischerweise im value-Feld eingebunden (z. B. "10 mail.example.com."). Möglicherweise müssen Sie die Formatierung je nach Provider-Version anpassen. Prüfen Sie die Hetzner DNS Terraform Provider-Dokumentation für Details.

    Anwenden

    export TF_VAR_dnscale_api_key="your-dnscale-key"
    export TF_VAR_hetzner_dns_token="your-hetzner-token"
     
    terraform init
    terraform plan    # Änderungen für beide Anbieter prüfen
    terraform apply   # Gleichzeitig an beide pushen

    Terraform erstellt Ressourcen bei beiden Anbietern parallel, sodass ein einziges apply alles aktualisiert. Für eine vertiefte Behandlung des DNScale-Providers siehe den Terraform-Provider-Leitfaden.

    DNSControl: Multi-Provider-Setup

    DNSControl hat native Multi-Provider-Unterstützung eingebaut. Sie können mehrere DNS-Provider an eine einzelne Domain anhängen, und DNSControl pusht identische Einträge an alle in einem Befehl.

    Anmeldedaten

    // creds.json
    {
      "dnscale": {
        "TYPE": "DNSCALE",
        "api_key": "your-dnscale-key"
      },
      "hetzner": {
        "TYPE": "HETZNER",
        "api_token": "your-hetzner-token"
      }
    }

    Halten Sie creds.json aus der Versionskontrolle heraus:

    echo "creds.json" >> .gitignore

    Konfiguration

    DNSControls DnsProvider()-Funktion akzeptiert mehrere Provider für eine einzelne Domain. Einträge werden automatisch an alle angehängten Provider gepusht:

    // dnsconfig.js
    var REG_NONE = NewRegistrar("none");
    var DSP_DNSCALE = NewDnsProvider("dnscale");
    var DSP_HETZNER = NewDnsProvider("hetzner");
     
    D("example.com", REG_NONE,
      DnsProvider(DSP_DNSCALE),
      DnsProvider(DSP_HETZNER),
     
      // A-Einträge
      A("@", "203.0.113.10", TTL(3600)),
      A("mail", "203.0.113.20", TTL(3600)),
     
      // IPv6
      AAAA("@", "2001:db8::1", TTL(3600)),
     
      // CNAME
      CNAME("www", "example.com.", TTL(3600)),
     
      // Mail
      MX("@", 10, "mail.example.com.", TTL(3600)),
     
      // SPF
      TXT("@", "v=spf1 mx -all", TTL(3600)),
     
    END);

    Das ist alles. Beide Provider sind auf derselben Domain gelistet, und DNSControl erledigt den Rest.

    Preview und Push

    # Sehen, was sich bei beiden Anbietern ändern würde
    dnscontrol preview
     
    # Änderungen an beide Anbieter pushen
    dnscontrol push

    Die preview-Ausgabe zeigt Änderungen pro Anbieter, sodass Sie überprüfen können, ob sowohl DNScale als auch Hetzner die korrekten Einträge erhalten, bevor Sie pushen.

    Weitere Details zu DNSControl mit DNScale finden Sie im DNSControl-Leitfaden.

    Einträge synchron halten

    Das größte Risiko bei Multi-Provider-DNS ist Drift — Einträge, die zwischen den Anbietern auseinanderlaufen. Ihr IaC-Tool löst dies, indem es die einzige Quelle der Wahrheit ist.

    IaC als Quelle der Wahrheit

    Bearbeiten Sie Einträge niemals direkt in den DNScale- oder Hetzner-Dashboards. Alle Änderungen gehen über Ihre Terraform- oder DNSControl-Konfiguration. Dies stellt sicher, dass beide Anbieter immer identische Einträge haben.

    CI/CD-Pipeline

    Automatisieren Sie Deployments, sodass Einträge bei jedem Merge nach main an beide Anbieter gepusht werden:

    # .github/workflows/dns.yml
    name: DNS Deploy
    on:
      push:
        branches: [main]
        paths: ["dns/**"]
     
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
     
          - name: Setup Terraform
            uses: hashicorp/setup-terraform@v3
     
          - name: Apply DNS changes
            working-directory: dns/
            env:
              TF_VAR_dnscale_api_key: ${{ secrets.DNSCALE_API_KEY }}
              TF_VAR_hetzner_dns_token: ${{ secrets.HETZNER_DNS_TOKEN }}
            run: |
              terraform init
              terraform apply -auto-approve

    Drift-Erkennung

    Führen Sie regelmäßige Prüfungen durch, um manuelle Änderungen oder API-Inkonsistenzen zu erkennen:

    # Terraform: Drift erkennen
    terraform plan -detailed-exitcode
    # Exit-Code 2 bedeutet Drift erkannt
     
    # DNSControl: Preview zeigt alle Unterschiede
    dnscontrol preview

    Planen Sie dies in CI ein (z. B. als täglicher Cron-Job) und alarmieren Sie bei unerwarteten Unterschieden.

    NS-Delegation beim Registrar

    Nach dem Deployment der Einträge bei beiden Anbietern aktualisieren Sie die NS-Einträge bei Ihrem Domain-Registrar, um Nameserver beider Anbieter einzuschließen.

    Ein typisches NS-Set sieht so aus:

    ns1.dnscale.eu
    ns2.dnscale.eu
    hydrogen.ns.hetzner.com
    oxygen.ns.hetzner.com
    helium.ns.hetzner.de

    Die genauen DNScale-Nameserver-Namen hängen von Ihrem Konto ab. Prüfen Sie Ihre Zonendetails im DNScale-Dashboard für die zugewiesenen Nameserver.

    Setzen Sie alle diese als NS-Einträge bei Ihrem Registrar. Die meisten Registrare erlauben beliebig viele Nameserver.

    Delegation verifizieren

    Nach der Aktualisierung der NS-Einträge (erlauben Sie bis zu 48 Stunden für die Propagierung) verifizieren Sie mit:

    dig NS example.com +short

    Sie sollten Nameserver beider Anbieter in der Antwort sehen. Sie können auch verifizieren, dass jeder Anbieter korrekt antwortet:

    # DNScale direkt abfragen
    dig @ns1.dnscale.eu example.com A +short
     
    # Hetzner direkt abfragen
    dig @hydrogen.ns.hetzner.com example.com A +short

    Beide sollten dieselbe IP-Adresse zurückgeben.

    Einschränkungen und Überlegungen

    DNSSEC

    Multi-Provider-DNSSEC ist komplex. Jeder Anbieter signiert die Zone mit eigenen Schlüsseln, daher benötigen Sie entweder:

    • Beide Anbieter unterstützen Multi-Signer-DNSSEC (RFC 8901) — noch nicht weit verbreitet
    • Ein Anbieter ist der Signierer und überträgt signierte Zonen an den anderen
    • DNSSEC bei Multi-Provider-Zonen auslassen, bis Multi-Signer-Unterstützung besser wird

    Für die meisten Setups ist das Auslassen von DNSSEC bei Multi-Provider-Zonen die pragmatische Wahl. Wenn DNSSEC eine harte Anforderung ist, ziehen Sie einen einzelnen Anbieter mit starken Verfügbarkeitsgarantien in Betracht. Siehe den DNSSEC-Leitfaden für Single-Provider-DNSSEC-Setup.

    TTL-Angleichung

    Halten Sie TTLs bei beiden Anbietern identisch. Unterschiedliche TTLs bedeuten, dass Resolver Einträge unterschiedlich lange zwischenspeichern, je nachdem welchen Anbieter sie abgefragt haben, was zu inkonsistentem Verhalten führt.

    Propagierungsverzögerungen

    Wenn Sie Änderungen pushen, verarbeiten beide Anbieter sie unabhängig. Es gibt ein kurzes Zeitfenster (meist Sekunden, manchmal Minuten), in dem ein Anbieter die neuen Einträge hat und der andere noch die alten liefert. Für die meisten Anwendungsfälle ist das in Ordnung — vermeiden Sie nur Änderungen, die bei teilweiser Anwendung Probleme verursachen würden.

    Anbieterspezifische Eintragstypen

    Beschränken Sie sich auf Standard-Eintragstypen, die beide Anbieter unterstützen: A, AAAA, CNAME, MX, TXT, SRV, CAA, NS. Anbieterspezifische Erweiterungen oder proprietäre Eintragstypen sind nicht portierbar.

    Nächste Schritte