Automating Cloudflare DNS Management with Terraform

Why use terraform for managing DNS records?
If you're responsible for managing DNS records on Cloudflare across multiple domains, you know how repetetive it can be to keep updating DNS records all the time. You log into the Cloudflare dashboard, go to the DNS settings, and manually change each record, making sure to double-check every entry.
Manual DNS management is not slow. Small typo can result in service interruptions, and without version control, tracking changes or reverting updates can take time. Also, once the DNS entries get propagated - it for sure will lead to a downtime for minutes if not hours.
At KubeNine, we use Cloudflare heavily for us and our customers. We manage multiple domains on Cloudflare and have a need to update DNS records fairly frequently. To make this process smoother - we started using Terraform to manage our DNS records on cloudflare. Instead of relying on manual updates, Terraform lets you define DNS records in code—bringing automation, version control, and consistency to your workflow.
How Terraform Improves DNS Management
- Automation – Define DNS configurations once and apply them consistently. Developers can create a pull request to add a new DNS record.
- Version Control – Track changes using Git.
- Security - No need to give everyone access to your cloudflare account - you can configure your cicd pipelines to run terraform code so that the modifications can be made only from your cicd pipeline.
Now, let’s set up Terraform for Cloudflare step by step.
Step 1: Finding your cloudflare zone ID
Before configuring Terraform, you need your Cloudflare Zone ID.
Method 1: Cloudflare Dashboard
- Log in to Cloudflare Dashboard.
- Select your domain.
- The Zone ID is displayed on the overview page.
Method 2: Using Cloudflare CLI
If you prefer automation, you can use Cloudflare’s CLI tool.
- Install
flarectl
from Cloudflare-Go. - Run the following command.
flarectl zone list
Step 2: Using cloudflare CLI for quick DNS management
Cloudflare CLI (flarectl
) allows quick modifications without using the dashboard.
Listing all DNS records
flarectl dns list --zone yourdomain.com
This retrieves and displays all DNS records for your domain.
Creating a Terraform directory
mkdir cloudflare-terraform && cd cloudflare-terraform
This creates a new folder and navigates into it, where all Terraform configuration files will be stored.
Defining the Cloudflare provider
Create a file called main.tf
and add the following:
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
This tells Terraform to use the Cloudflare provider and authenticate using the API token.
Creating A record
resource "cloudflare_record" "example_dns_record" {
zone_id = var.cloudflare_zone_id
name = "example.yourdomain.com"
type = "A"
content = "192.168.1.1"
ttl = 3600
proxied = true
}
This creates an A record for example.yourdomain.com
, pointing to 192.168.1.1
, with a TTL of 3600 seconds. The proxied = true
setting enables Cloudflare's proxy for this record.
Step 4: Managing multiple DNS records dynamically
Instead of defining each record manually, a dynamic configuration makes things more efficient.
Using variables for multiple records
Create a variables.tf
file:
variable "dns_records" {
type = list(object({
name = string
type = string
content = string
ttl = number
}))
}
resource "cloudflare_record" "bulk_records" {
count = length(var.dns_records)
zone_id = var.cloudflare_zone_id
name = var.dns_records[count.index].name
type = var.dns_records[count.index].type
content = var.dns_records[count.index].content
ttl = var.dns_records[count.index].ttl
}
This configuration allows you to define multiple DNS records in a list instead of creating separate blocks for each.
Example record definitions
In terraform.tfvars
, define multiple records:
dns_records = [
{ name = "app.yourdomain.com", type = "A", content = "192.168.1.1", ttl = 3600 },
{ name = "api.yourdomain.com", type = "CNAME", content = "example.com", ttl = 300 }
]
Step 5: Applying Terraform changes
Initializing terraform
terraform init
Previewing changes
terraform plan
This displays the planned changes before applying them.
Applying changes
terraform apply -auto-approve
This applies the changes and creates the DNS records in Cloudflare.
Edit main.tf
and re-run:
terraform apply -auto-approve
This updates existing DNS records.
There are times when you might need to delete all DNS records managed by Terraform. This could be for reasons such as testing, removing outdated records, or shutting down a setup that you no longer require.
terraform destroy -auto-approve
This will remove all DNS records created by terraform, insuring a complete rollback.
Bonus: Configure PR workflow
Here’s a screenshot of how we have configured terraform report on PR creation. This helps us manage all the DNS records from a single place with version control

Step 6: Troubleshooting and best practices
Common issues and solutions
Issue | Cause | Solution |
---|---|---|
Authentication error | Incorrect API token | Verify |
DNS record not updating | Conflict with manual changes | Delete conflicting record from Cloudflare |
API rate limit reached | Too many requests at once | Use -parellelism=1 |
Security best practices
- Do not hardcode API tokens
- Use environment variables:
export CLOUDFLARE_API_TOKEN="your-token"
- Use terraform modules:
- Organise configurations for different environments (dev, prod).
Conclusion
In a production environment you should consider managing DNS records with version control. With cloudflare support terraform - there’s no better option than that for managing DNS records.
We can easily configure a cicd pipeline to manage the entire workflow. This allows developers to manage the DNS records from a single place.
Would like to get this configured for your organisation? KubeNine can help, reach out to us!