Drive Cloudflare DNS, CDN, and WAF from flows.

Update DNS the moment Terraform writes the new IP. Purge cache when Argo CD reports Healthy. Block IPs from alert payloads. Push Worker scripts and KV values from data pipelines. Zone metadata as flow input, multi-zone batch operations, all in one execution history.

Around every zone, every record, every cache miss.

Cloudflare runs the edge. Kestra wires it into the rest of your stack: DNS updated from Terraform output, cache purged when the deploy succeeds, WAF rules opened by an alert and closed by a schedule. The Cloudflare dashboard, the API tokens, and the edge runtime stay where they are.

DNS records driven by what's happening upstream

dns.records.Upsert creates a record if it does not exist, otherwise patches the first match by name and type. Pair it with Terraform output to keep an A record in sync with a new EC2 IP. dns.records.Batch handles bulk Create / Update / Delete in one call. dns.records.List feeds reconciliation flows. The dashboard stops being the place anyone clicks to add an A record.

Cache purge as the final deploy step, not a separate runbook

cache.Purge fires after Argo CD reports Healthy, after a Pages deploy completes, or after a Worker script is deployed. Scope by tag, hostname, or URL list. The deploy execution is not marked successful until the cache is fresh, so the rollback target and the cache state stay aligned across rollouts.

WAF access rules opened by alerts, closed by schedule

waf.accessrules.Create with mode block, challenge, or whitelist. Trigger from a Slack alert payload, a PagerDuty event, or an Athena query that surfaces abuse. Auto-expire emergency rules with a scheduled waf.accessrules.Delete one hour later. waf.accessrules.List reconciles reality with the declared rule set in Git.

Workers KV writes from data pipelines

compute.kv.Write pushes bulk key-value pairs into a Workers KV namespace from any upstream source: a dbt model output, a Snowflake query, a Kafka stream. compute.kv.Get reads back for verification. compute.namespaces.Create provisions a new KV namespace per environment. The edge cache becomes a first-class output of your data flow.

Worker script lifecycle as flow tasks

workers.scripts.Deploy uploads or replaces a Worker by name (PUT is idempotent). workers.scripts.Get fetches the current source for diffing. workers.scripts.List enumerates every script on the account for inventory. workers.dynamic.Run posts inline JavaScript to a gateway Worker for ad-hoc edge logic during a flow.

Zone-aware multi-zone operations in one execution

zones.List returns every zone on the account. A ForEach over the result iterates and runs dns.records.* per zone, no hardcoded zone IDs. zones.Get resolves a zone ID from a hostname so downstream tasks do not need lookup hops. Multi-tenant SaaS shops with hundreds of customer zones run reconciliation flows that span the whole account.

How edge teams use Cloudflare and Kestra

Patterns engineering teams run in production today. Each one shows the flow end to end, with the real plugin classes in play.

DNS sync

Update Cloudflare DNS the moment Terraform writes the new IP

terraform apply finishes and writes the new EC2 IP to an output. Kestra picks up the output value, calls dns.records.Upsert against the right zone with the new A record content, then purges any cached responses for that hostname. The runbook step that used to be a Slack ping for someone to update the dashboard disappears.

Upsert handles new-record and update cases

No branching between Create and Update. Upsert patches the first matching record by name+type, or creates it if missing.

TF output flows forward into the DNS task

The IP that Terraform wrote becomes the content field on dns.records.Upsert. No copy-paste, no manual edit.

Cache purge follows immediately

Any cached response for the hostname is invalidated so clients pick up the new origin on the next request.

One execution ID spans Terraform and Cloudflare

Debugging the rollout starts in Kestra. The execution links to the Terraform plan output and the Cloudflare record ID.

terraform apply
infra change
extract output
new IP / hostname
upsert DNS
dns.records.Upsert
purge cache
by hostname
notify
Slack with record ID
Deploy gate

Purge cache the moment the new deploy reports Healthy

Argo CD finishes syncing the new version of the app and reports Healthy via the workflow_run webhook. Kestra catches the webhook, runs cache.Purge against the affected hostname (or by tag for finer scoping), then posts to Slack with the deploy URL. Until the purge succeeds, the deploy is not considered complete.

Deploy success now includes cache state

The flow is not done until Purge returns 200. Rolling back to a stale-cache state is not possible.

Tag-scoped purges for fine control

Tags set in the Cache-Tag header purge only that subset. Hostname-wide purge is the broad option.

Post-purge probe confirms freshness

An HTTP HEAD with cache-control: no-cache verifies the origin response, catches cache rules that block the purge.

argo cd healthy
webhook back
purge cache
by hostname or tag
verify
HEAD against /healthz
notify
Slack with URL
Incident

Block an abusive IP from a PagerDuty alert, auto-expire in 1 hour

PagerDuty fires when a Cloudflare Analytics threshold breaches. The webhook payload reaches a Kestra trigger with the offending IP. The flow calls waf.accessrules.Create with mode: block and notes referencing the incident ID. A second scheduled flow runs one hour later, queries waf.accessrules.List for rules tagged with the incident, and deletes them. Emergency block without a dashboard click.

Block is reactive, expiry is automatic

No human required to remove the rule. The flow's second leg deletes it when the threat window closes.

Incident ID baked into rule notes

Every emergency rule references the PagerDuty incident, so audit later answers exactly who and what triggered the block.

Reconcile against a Git-declared rule set

A separate flow lists rules with no incident tag, compares to a YAML manifest in Git, and reports drift.

pagerduty alert
webhook
create block rule
waf.accessrules.Create
notify SOC
Slack with rule ID
scheduled cleanup
1 hour later
delete rule
waf.accessrules.Delete
Multi-zone

Reconcile DNS records across every zone in one execution

A YAML manifest in Git declares zone + record mappings. Kestra clones the repo, calls zones.List to enumerate the account, and runs dns.records.Batch per zone to align declared records with reality. A pre-flight dryRun on a Schedule posts the diff to Slack for review before the apply flow runs. Multi-tenant zones, hundreds of records, one flow definition.

Git is the declared state, Cloudflare is reconciled

Edit a YAML, push, the next schedule applies. No dashboard clicks for records that live in the manifest.

Batch keeps the request count down

Per zone, one dns.records.Batch combines create + update + delete instead of one API call per record.

Drift surfaces before it bites

Records added in the dashboard but missing in Git get flagged in the drift report, not silently overwritten on next apply.

weekly schedule
cron
clone manifest
from Git
list zones
zones.List
ForEach zone
per-zone batch
batch records
Create/Update/Delete
drift report
Slack summary
Terraform is quite a big deal for us because that's basically how we work most of the day to roll out changes. Kestra will be the entity to roll out everything. This should resolve the issues we are facing currently with everyone working in parallel.
BSI Software

Blueprints for Cloudflare orchestration.

One blueprint per use case above. Copy the YAML, set your Cloudflare API token, point at your zone, ship it.

DNS upsert when Terraform writes a new IP
Cache purge after Argo CD reports Healthy
Multi-zone DNS reconciliation from a Git manifest

Sync a Cloudflare A record with terraform output, then purge cache

terraform apply produces a new IP output. The flow upserts the matching A record in Cloudflare, purges the cache for that hostname, and posts a Slack message with the record ID and the new content.

Explore Blueprints

Listen for the deploy webhook, purge cache, verify with a probe

A Webhook trigger receives the Argo CD workflow_run completion. The flow calls cache.Purge by hostname, then runs an HTTP HEAD with cache-control: no-cache to verify the origin response. Slack confirms with the deploy URL.

Explore Blueprints

Iterate every zone on the account, apply declared records in one batch each

Weekly schedule. Clone the manifest repo. List every zone on the account. Per zone, parse the manifest, build the declared record set, and apply with dns.records.Batch. A drift summary posts to Slack showing records changed per zone.

Explore Blueprints

Kestra vs Cloudflare automation alternatives

Capability
Cloudflare Dashboard (manual)
Terraform Cloudflare provider
Custom script + Cloudflare API
DNS upsert as a flow task
dns.records.Upsert handles create-or-patch, no branching
Dashboard click per recordterraform plan/apply per changeCustom HTTP code
Bulk DNS Create + Update + Delete in one call
dns.records.Batch with three arrays in one request
Per-record manualOne resource per record, no native batchCustom batching code
Cache purge as a deploy step
cache.Purge by host, tag, or URL list
Manual or post-deploy scriptNot in scope (state, not action)Custom HTTP call
WAF rule lifecycle (create + auto-expire)
Create + scheduled Delete with one rule definition
Dashboard click on, dashboard click offResource lifecycle, no time-based expiryCustom code with a TTL store
Workers KV bulk writes from a data flow
compute.kv.Write with batch payload
wrangler kv:bulk put from shellNot nativeCustom HTTP
Worker script deploy as a flow task
workers.scripts.Deploy, idempotent PUT
wrangler from a runnerCustom provider, multipart upload requiredCustom HTTP
Multi-zone iteration in one execution
zones.List + ForEach + per-zone task
Per-zone manualfor_each on resources, plan time onlyCustom loop
Chain Cloudflare with Terraform, Argo CD, dbt
Outputs flow into Cloudflare tasks and back out
No chainProvider per tool, no chain semanticsCustom glue
Self-hosted, air-gapped, OSS edition
Self-hosted by default, OSS edition free
SaaS onlySelf-hosted or HCPSelf-hosted

Cloudflare & Kestra: common questions

Find answers to your questions right here, and don't hesitate to Contact Us if you couldn't find what you're looking for.

See How

Ready to wire Cloudflare into the rest of your stack?

Drive DNS records from Terraform output, purge cache the moment deploys ship, block IPs from alert payloads with auto-expiry, deploy Workers from CI, and reconcile records across every zone weekly. Open source, self-hosted, event-driven.