Si l'internet traditionnel est un vaste système de câbles physiques et de centres de données, Cloudflare est le système d'exploitation intelligent construit par-dessus. Il gère la sécurité, le routage du trafic, les performances et le calcul en périphérie mondiale. Il est aujourd'hui presque impossible de l'éviter — la plupart des serveurs web que je gère sont exposés en premier lieu via le DNS Cloudflare, et bénéficient immédiatement de ses capacités de sécurité et de performance.
La gestion du DNS chez Cloudflare peut se faire manuellement, et c'est exactement ainsi que je gérais tous mes domaines jusqu'à cet article.
D'abord, sur NixOS, activer cf-terraforming et terraform. Cette étape peut être lente car elle semble nécessiter une compilation, du moins sur ma machine NixOS.
{ pkgs ? import <nixpkgs> { config.allowUnfree = true; } }:
pkgs.mkShell {
buildInputs = with pkgs; [
pkgs.terraform
pkgs.cf-terraforming
];
shellHook = ''
echo "Cloudflare IaC environment loaded!"
'';
}
Une option plus rapide est de récupérer directement le script
Cloner le dépôt et initialiser l'espace de travail Terraform :
terraform init
Puis exporter votre configuration DNS Cloudflare :
sh ./exportZones.sh
Deux choses vont se produire :
zones.tf sera créé à la racine du dépôt, ainsi que imports.tfdns_<domain>.tf et un fichier import_dns_<domain>.tf seront générés par domaineVoici le contenu du script exportZones.sh :
#!/bin/sh
if [ -f ".env.local" ]; then
CLOUDFLARE_API_TOKEN=$(grep -E '^CLOUDFLARE_API_TOKEN=' .env.local | cut -d '=' -f 2- | tr -d '"' | tr -d "'")
CLOUDFLARE_ACCOUNT_ID=$(grep -E '^CLOUDFLARE_ACCOUNT_ID=' .env.local | cut -d '=' -f 2- | tr -d '"' | tr -d "'")
echo "Loaded API token from .env.local"
fi
if [ -z "$CLOUDFLARE_API_TOKEN" ]; then
echo "ERROR: CLOUDFLARE_API_TOKEN is missing from .env.local and environment." >&2
exit 1
fi
if [ -z "$CLOUDFLARE_ACCOUNT_ID" ]; then
echo "ERROR: CLOUDFLARE_ACCOUNT_ID is missing from .env.local and environment." >&2
exit 1
fi
export CLOUDFLARE_API_TOKEN
export CLOUDFLARE_ACCOUNT_ID
echo "1. Generating zones file..."
cf-terraforming generate --resource-type cloudflare_zone > zones.tf
echo "1.1. Generating root-level zone imports..."
awk '
/resource "cloudflare_zone"/ {
if (match($0, /terraform_managed_resource_[a-f0-9]{32}_[0-9]+/)) {
resource_name = substr($0, RSTART, RLENGTH)
token = substr($0, RSTART + 27, RLENGTH - 27)
split(token, parts, "_")
zone_id = parts[1]
print "import {"
print " to = cloudflare_zone." resource_name
print " id = \"" zone_id "\""
print "}"
print ""
}
}
' "zones.tf" > "import_zones.tf"
echo "2. Processing zones and exporting DNS records to root..."
awk '
/resource "cloudflare_zone"/ {
if (match($0, /terraform_managed_resource_[a-f0-9]+/)) {
id = substr($0, RSTART + 27, RLENGTH - 27)
}
}
/^[ \t]*zone[ \t]*=/ {
if (match($0, /"[^"]+"/)) {
domain = substr($0, RSTART + 1, RLENGTH - 2)
}
if (id != "" && domain != "") {
print id "|" domain
id = ""
domain = ""
}
}
' "zones.tf" | while IFS='|' read -r zone_id domain_name; do
if [ -n "$zone_id" ] && [ -n "$domain_name" ]; then
DNS_FILE="dns_${domain_name}.tf"
IMPORTS_FILE="import_dns_${domain_name}.tf"
echo "Exporting DNS for: $domain_name -> $DNS_FILE"
CLOUDFLARE_ACCOUNT_ID="" cf-terraforming generate --resource-type cloudflare_record --zone "$zone_id" > "$DNS_FILE"
echo "Calculating imports for $domain_name (Zone ID: $zone_id)"
awk -v zid="$zone_id" '
/resource "cloudflare_record"/ {
if (match($0, /terraform_managed_resource_[a-f0-9]{32}_[0-9]+/)) {
resource_name = substr($0, RSTART, RLENGTH)
token = substr($0, RSTART + 27, RLENGTH - 27)
split(token, parts, "_")
rec_id = parts[1]
print "import {"
print " to = cloudflare_record." resource_name
print " id = \"" zid "/" rec_id "\""
print "}"
print ""
}
}
' "$DNS_FILE" > "$IMPORTS_FILE"
fi
done
echo "Done! Zones, import_zones.tf, and individual dns/import files are saved at the root."
Vérifiez vos fichiers de zones et l'export DNS.
Votre dépôt devrait ressembler à ceci — les fichiers d'import et l'état ne sont pas versionnés :
.
├── backend.tf --> Optional: your backend configuration
├── domains --> The domains you configure in your Cloudflare account
│ ├── dns_alcanzatuproposito.com.tf
│ ├── dns_comunidadsana.com.tf
│ ├── dns_emely.es.tf
│ ├── dns_jugandoalacomidita.com.tf
│ ├── dns_miespazio.pe.tf
│ └── versions.tf
├── exportZones.sh
├── LICENSE
├── modules.tf
├── README.md
├── shell.nix
├── versions.tf
└── zones.tf --> Zone files
terraform plan -out "plan.tfplan"
Nous avons exporté les imports, les zones et les fichiers DNS depuis Cloudflare. Comme les formats de lecture et d'écriture diffèrent légèrement, Terraform planifiera avec des imports et des modifications, mais sans ajout ni suppression.
...
Plan: 41 to import, 0 to add, 36 to change, 0 to destroy.
Saved the plan to: plan.tfplan
...
Exécutez maintenant apply pour persister l'état dans votre backend :
terraform apply "plan.tfplan"
Après cette étape, terraform plan devrait afficher :
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
Cela vous permet de gérer votre configuration DNS, de planifier et d'appliquer des changements via Terraform, ou de connecter une GitHub Action pour déployer automatiquement votre configuration DNS. Dans le prochain article, je verrai comment gérer l'état Terraform avec Forgejo Packages et configurer un backend Terraform pour l'utiliser.
Cloudflare · Terraform · Git