ProjectsImplementation project

Active2 min read

Cloudflare Gateway Ad Blocking with Terraform

A Terraform project that consumes remote domain feeds, normalizes them into Cloudflare Zero Trust lists and builds a Gateway DNS blocking policy from the generated data.

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.