This project manages DNS-level advertising and tracker blocking through Cloudflare Gateway using Terraform.
Rather than manually maintaining a large domain list in the dashboard, Terraform retrieves configured public feeds, normalizes the records, creates Cloudflare Zero Trust domain lists and uses those lists in a Gateway DNS policy.
Data flow
Remote domain sources
↓
Terraform HTTP data sources
↓
Normalization / filtering
↓
Chunked Cloudflare domain lists
↓
Gateway DNS block policy
Cloudflare remains the enforcement layer; Terraform manages the data and policy definitions.
Remote sources
The project defines enabled domain feeds as configuration and retrieves them with Terraform HTTP data sources.
Response status is validated so an upstream HTTP error is not treated as a valid domain list.
Domain processing
The configuration handles common list styles including bare domains and hosts-file-like entries.
Processing removes irrelevant lines, extracts the domain value, de-duplicates the result and produces a canonical set for Cloudflare.
Cloudflare lists
The normalized set is split into manageable chunks and represented as cloudflare_zero_trust_list resources.
Each item is created as a domain entry with a descriptive label.
Gateway enforcement
A cloudflare_zero_trust_gateway_policy resource references the generated domain lists and applies a DNS block action.
The policy name, description, precedence and enablement are configurable rather than embedded in the resource.
Lifecycle handling
List and policy resources use lifecycle behaviour intended to reduce enforcement gaps when Terraform needs to replace an object.
The project also keeps the ad-blocking feature optional so the Terraform configuration can be planned or reused without forcing the policy to exist.
Security and state
Cloudflare credentials are supplied outside the repository. The project assumes infrastructure state is protected appropriately because Terraform state is operationally sensitive even when secrets are not hard-coded in configuration.
Typical workflow
terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply
Because the upstream feeds are external dependencies, I review source changes and unexpectedly large list deltas before treating automated updates as routine.
Related article
See DNS-Level Ad Blocking with Cloudflare Gateway and Terraform for the architecture, feed-handling and policy-lifecycle lessons from the project.