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:
- Definisci i tuoi record una volta in Terraform o DNSControl
- Invia record identici a entrambi DNScale e Hetzner DNS
- Imposta i record NS presso il tuo registrar puntando ai nameserver di entrambi i provider
- 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 dueEntrambi 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:
- Un account DNScale con una chiave API — Ottieni la tua chiave API
- Un account Hetzner DNS con un token API — Hetzner DNS Console
- Terraform (v1.0+) o DNSControl (v4.0+) installati
- 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 simultaneamenteTerraform 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" >> .gitignoreConfigurazione
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 pushL'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-approveRilevamento 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 previewPianifica 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.deI 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 +shortDovresti 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 +shortEntrambi 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
- Gestire il DNS con Terraform — approfondimento sul provider Terraform DNScale
- Gestire il DNS con DNSControl — configurazione completa di DNSControl
- Configurazione DNSSEC — configura DNSSEC per zone con provider singolo
- Global DNS Resolution Balancing — distribuzione geografica del traffico attraverso i nodi DNS