← Blog

Alexis · 2026-10-12

DNS Cloudflare : la couche omniprésente de l'infrastructure internet mondiale

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.

Préparer un environnement shell IaC

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

Exporter la configuration DNS Cloudflare et initialiser Terraform

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 :

Voici 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

Vérifier que Terraform fonctionne correctement après l'export

  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.

Stack

Cloudflare · Terraform · Git