Search code examples
automationdnscommand-line-interfaceterraformcloudflare

How to change multiple sites dns in CloudFlare account?


I have a lot of sites on an CloudFlare account, sometimes when servers are migrate, i need to change every domain DNS in CF manually. How can I use some tool or script, that helps me to download all domains info, and than easy change it? Maybe some Terraform example? I didnt use Terraform yet, so just thinking about ways how to automate this proccess. Tnx.


Solution

  • Yes, you can use Terraform for this. There are an official Cloudflare Provider, the documentation for which you can find here.

    When using the provider "directly", your Terraform configuration will look like this:

    terraform {
      required_providers {
        cloudflare = {
          source  = "cloudflare/cloudflare"
          version = ">= 3.12.1"
        }
      }
    }
    
    variable "cloudflare_api_token" {
      type      = string
      sensitive = true
    }
    
    provider "cloudflare" {
      api_token = var.cloudflare_api_token
    }
    
    resource "cloudflare_zone" "acme_com" {
      zone = "acme.com"
    }
    

    You may be interested in the following Cloudflare resources to use them in your configuration:

    Also, you can use this module. Then your configuration may look like this:

    terraform {
      required_providers {
        cloudflare = {
          source  = "cloudflare/cloudflare"
          version = ">= 3.12.1"
        }
      }
    }
    
    variable "cloudflare_api_token" {
      type      = string
      sensitive = true
    }
    
    provider "cloudflare" {
      api_token = var.cloudflare_api_token
    }
    
    module "acme_com" {
      source = "registry.terraform.io/alex-feel/zone/cloudflare"
      version = "1.7.0"
      zone = "acme.com"
    }
    

    There are examples to help you get started with the module.

    And here is a concrete, ready-to-use example that you can use in your specific case when using the module:

    terraform {
      required_providers {
        cloudflare = {
          source  = "cloudflare/cloudflare"
          version = ">= 3.12.1"
        }
      }
    }
    
    variable "cloudflare_api_token" {
      type      = string
      sensitive = true
    }
    
    provider "cloudflare" {
      api_token = var.cloudflare_api_token
    }
    
    locals {
      # All your zones go here
      zones = ["acme.com", "example.com"]
      # Your IP for A records for all the zones goes here
      ip = "192.0.2.1"
    }
    
    module "all_domains" {
      source  = "registry.terraform.io/alex-feel/zone/cloudflare"
      version = "1.7.0"
    
      for_each = toset(local.zones)
    
      zone = each.value
    
      records = [
        {
          record_name = "a_main"
          type        = "A"
          value       = local.ip
        }
      ]
    }
    

    In this case, it will be enough for you to list all your domains in the zones variable and specify the desired IP in the ip variable. As a result, an A record with the specified IP will be created for each of your domains.

    To get all your zones you can use Cloudflare API List Zones method. So your request will look like this:

    curl --request GET \
      --url https://api.cloudflare.com/client/v4/zones \
      --header 'Authorization: Bearer YOUR_TOKEN'