Vi presentiamo PostScale -- API email per invii transazionali, ricezione e indirizzi mascherati. PostScale

    DNS multi-provider con Terraform e DNSControl

    Distribuisci zone DNS su DNScale e Hetzner DNS per la ridondanza usando Terraform o DNSControl.

    Affidarsi a un singolo provider DNS significa avere un singolo punto di errore. Se quel provider va giù — a causa di un'interruzione, un attacco DDoS o una configurazione errata — i tuoi domini diventano irraggiungibili. Il DNS multi-provider elimina questo rischio servendo la stessa zona da due provider indipendenti contemporaneamente.

    Questa guida illustra la configurazione di DNScale e Hetzner DNS come provider duali usando Terraform o DNSControl. Entrambi gli strumenti ti permettono di definire i record una sola volta e inviarli a entrambi i provider, mantenendo tutto sincronizzato senza duplicazione manuale.

    Perché il DNS multi-provider

    Il DNS è la base di ogni servizio Internet che gestisci. Un'interruzione del provider non significa solo che il tuo sito web è irraggiungibile — significa che le email smettono di arrivare, le API diventano inaccessibili e i servizi che dipendono da record SRV o TXT si guastano.

    Il DNS multi-provider funziona delegando il tuo dominio ai nameserver di entrambi i provider. I resolver in tutto il mondo interrogheranno qualunque set di nameserver risponda, quindi se un provider è inattivo, l'altro continua a servire le risposte.

    Quando ha senso il multi-provider?

    • Domini di produzione dove il downtime ha un costo reale
    • Ambienti di compliance che richiedono ridondanza
    • Servizi globali dove la copertura dei provider varia per regione

    Quando è eccessivo? Per domini di sviluppo, strumenti interni o domini dove pochi minuti di downtime sono accettabili, un singolo provider con buon uptime è solitamente sufficiente.

    Come funziona

    Il concetto è semplice:

    1. Definisci i tuoi record una volta in Terraform o DNSControl
    2. Invia record identici a entrambi DNScale e Hetzner DNS
    3. Imposta i record NS presso il tuo registrar puntando ai nameserver di entrambi i provider
    4. I resolver interrogano uno dei due provider — chi risponde per primo vince
    ┌──────────────┐
    │   Registrar  │
    │              │
    │ Record NS:  │
    │  ns1.dnscale │
    │  ns2.dnscale │
    │  hydrogen.ns │  ← Hetzner
    │  oxygen.ns   │  ← Hetzner
    └──────┬───────┘
    
    
    ┌──────────────┐     ┌──────────────┐
    │   DNScale    │     │  Hetzner DNS
    │              │     │              │
    │ example.com  │     │ example.com  │
    A, MX, TXT  │     │  A, MX, TXT
    │ (identici)   │     │ (identici)   │
    └──────────────┘     └──────────────┘
           ▲                    ▲
           │    ┌──────────┐    │
           └────│ Resolver │────┘
                └──────────┘
           Interroga uno dei due

    Entrambi i provider contengono gli stessi record. Il tuo strumento IaC è l'unica fonte di verità, e entrambi i provider sono semplicemente specchi di quella verità.

    Prerequisiti

    Ti serviranno:

    1. Un account DNScale con una chiave API — Ottieni la tua chiave API
    2. Un account Hetzner DNS con un token API — Hetzner DNS Console
    3. Terraform (v1.0+) o DNSControl (v4.0+) installati
    4. Un dominio di cui hai il controllo con accesso per impostare i record NS presso il registrar

    Terraform: configurazione multi-provider

    Terraform rende il DNS multi-provider pulito con il suo supporto nativo per provider multipli e cicli for_each. Definisci i tuoi record una volta in un blocco locals e li crei in entrambi i provider.

    Configurazione dei provider

    # 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"
    }

    Definisci i record una volta

    La chiave del DNS multi-provider con Terraform è definire i record in un unico posto. Usa locals per creare un set di record condiviso:

    # records.tf
    locals {
      dns_records = {
        # Record A
        "root-a" = {
          name  = "@"
          type  = "A"
          value = "203.0.113.10"
          ttl   = 3600
        }
        "www-a" = {
          name  = "www"
          type  = "CNAME"
          value = "example.com."
          ttl   = 3600
        }
        # Posta
        "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
        }
      }
    }

    Crea in entrambi i provider

    # 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
    }

    Per i record MX su Hetzner DNS, la priorità è tipicamente inclusa nel campo value (es. "10 mail.example.com."). Potresti dover adattare la formattazione in base alla versione del provider. Consulta la documentazione del provider Terraform Hetzner DNS per i dettagli.

    Applica

    export TF_VAR_dnscale_api_key="your-dnscale-key"
    export TF_VAR_hetzner_dns_token="your-hetzner-token"
     
    terraform init
    terraform plan    # Rivedi le modifiche per entrambi i provider
    terraform apply   # Invia a entrambi simultaneamente

    Terraform crea le risorse in entrambi i provider in parallelo, quindi un singolo apply aggiorna tutto. Per un approfondimento specifico sul provider DNScale, vedi la guida al provider Terraform.

    DNSControl: configurazione multi-provider

    DNSControl ha il supporto nativo multi-provider integrato. Puoi associare più provider DNS a un singolo dominio, e DNSControl invia record identici a tutti in un unico comando.

    Credenziali

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

    Mantieni creds.json fuori dal controllo di versione:

    echo "creds.json" >> .gitignore

    Configurazione

    La funzione DnsProvider() di DNSControl accetta provider multipli per un singolo dominio. I record vengono automaticamente inviati a tutti i provider associati:

    // 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),
     
      // Record A
      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)),
     
      // Posta
      MX("@", 10, "mail.example.com.", TTL(3600)),
     
      // SPF
      TXT("@", "v=spf1 mx -all", TTL(3600)),
     
    END);

    Tutto qui. Entrambi i provider sono elencati sullo stesso dominio e DNSControl gestisce il resto.

    Anteprima e push

    # Vedi cosa cambierebbe su entrambi i provider
    dnscontrol preview
     
    # Applica le modifiche a entrambi i provider
    dnscontrol push

    L'output di preview mostra le modifiche per provider, così puoi verificare che sia DNScale che Hetzner riceveranno i record corretti prima del push.

    Per maggiori dettagli su DNSControl con DNScale, vedi la guida DNSControl.

    Mantenere i record sincronizzati

    Il rischio maggiore con il DNS multi-provider è il drift — record che si desincronizzano tra i provider. Il tuo strumento IaC risolve questo problema essendo l'unica fonte di verità.

    IaC come fonte di verità

    Non modificare mai i record direttamente nelle dashboard di DNScale o Hetzner. Tutte le modifiche passano attraverso la tua configurazione Terraform o DNSControl. Questo garantisce che entrambi i provider abbiano sempre record identici.

    Pipeline CI/CD

    Automatizza i deployment affinché i record vengano inviati a entrambi i provider ad ogni merge su main:

    # .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

    Rilevamento del drift

    Esegui controlli periodici per individuare modifiche manuali o inconsistenze API:

    # Terraform: rileva il drift
    terraform plan -detailed-exitcode
    # Exit code 2 significa drift rilevato
     
    # DNSControl: preview mostrerà qualsiasi differenza
    dnscontrol preview

    Pianifica questo nel CI (es. un cron job giornaliero) e genera alert per differenze inattese.

    Delega NS presso il tuo registrar

    Dopo aver distribuito i record a entrambi i provider, aggiorna i record NS presso il tuo registrar di dominio per includere i nameserver sia di DNScale che di Hetzner.

    Un tipico set NS si presenta così:

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

    I nomi esatti dei nameserver DNScale dipendono dal tuo account. Controlla i dettagli della tua zona nella dashboard di DNScale per i nameserver assegnati.

    Imposta tutti questi come record NS presso il tuo registrar. La maggior parte dei registrar ti consente di aggiungere tutti i nameserver necessari.

    Verifica la delega

    Dopo aver aggiornato i record NS (attendi fino a 48 ore per la propagazione), verifica con:

    dig NS example.com +short

    Dovresti vedere nameserver di entrambi i provider nella risposta. Puoi anche verificare che ogni provider risponda correttamente:

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

    Entrambi dovrebbero restituire lo stesso indirizzo IP.

    Limitazioni e considerazioni

    DNSSEC

    Il DNSSEC multi-provider è complesso. Ogni provider firma la zona con le proprie chiavi, quindi hai bisogno di:

    • Entrambi i provider che supportino DNSSEC multi-signer (RFC 8901) — non ancora ampiamente supportato
    • Un provider che firmi e trasferisca le zone firmate all'altro
    • Saltare DNSSEC sulle zone multi-provider finché il supporto multi-signer non migliora

    Per la maggior parte delle configurazioni, saltare DNSSEC sulle zone multi-provider è la scelta pragmatica. Se DNSSEC è un requisito imprescindibile, considera l'uso di un singolo provider con forti garanzie di uptime. Vedi la guida DNSSEC per la configurazione DNSSEC con provider singolo.

    Allineamento TTL

    Mantieni i TTL identici su entrambi i provider. TTL non corrispondenti significano che i resolver memorizzano nella cache i record per durate diverse a seconda del provider interrogato, portando a comportamenti inconsistenti.

    Ritardi di propagazione

    Quando invii le modifiche, entrambi i provider le elaborano indipendentemente. C'è una breve finestra (solitamente secondi, a volte minuti) in cui un provider ha i nuovi record e l'altro serve ancora quelli vecchi. Per la maggior parte dei casi d'uso questo va bene — evita solo di fare modifiche che si romperebbero se applicate parzialmente.

    Tipi di record specifici del provider

    Attieniti ai tipi di record standard supportati da entrambi i provider: A, AAAA, CNAME, MX, TXT, SRV, CAA, NS. Le estensioni specifiche del provider o i tipi di record proprietari non saranno portabili.

    Prossimi passi