A production-ready, zero-unnecessary-interaction Python CLI tool to clone transferable Cloudflare configuration from a source domain to a target domain—even across completely different Cloudflare accounts.
It features intelligent domain transformation, modern Rulesets API support, automatic target snapshots, strict DNS mutation blocks, and post-migration verification.
- Flexible Authentication: Supports modern Cloudflare API Tokens (recommended) or Global API Key + Email via
config.yamlor environment variables. - Zero-Fuss Configuration: Put your credentials and domain names in
config.yamland run. No interactive prompts for IDs or domains. - Cross-Account Support: Discovers and authenticates source and target zones independently. Works seamlessly across separate Cloudflare accounts.
- Absolute DNS Safety: Hard-coded safety blocks prevent reading, exporting, modifying, or creating DNS records or nameserver settings.
- Modern Cloudflare Rulesets API: Clones Origin Rules, Cache Rules, Dynamic Redirects, Transform Rules, WAF Custom Rules, Rate Limiting Rules, Snippets, Custom Errors, and transferable Zone Settings.
- Intelligent Domain Transformation: Context-aware transformation across apex domains, subdomains, wildcards, URLs, Worker routes, and complex Cloudflare expressions without altering unrelated domains (e.g.,
external-example.comremains untouched). - Automatic Target Backups: Backs up the target zone's transferable configuration before making any mutations (
backups/YYYY-MM-DD_HH-MM-SS/target_backup.json). - Rollback Protection: Automatically attempts safe rollback if any mutation fails during execution.
- Idempotency: Running the tool multiple times will not duplicate rules or reapply unchanged settings.
- Post-Migration Verification: Re-queries Cloudflare to verify that the target matches the expected state, outputting a terminal summary and a JSON report (
reports/YYYY-MM-DD_HH-MM-SS.json).
- Python 3.10+
# Clone the repository
git clone git@github.com:s7net/cloudflare-zone-cloner.git
cd cloudflare-zone-cloner
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -e .Copy config.example.yaml to config.yaml:
cloudflare:
api_token: "YOUR_CLOUDFLARE_API_TOKEN"
migration:
source_domain: "example.com"
target_domain: "example.net"If a domain exists in multiple Cloudflare accounts (or if migrating the same domain name across accounts):
migration:
source_domain: "example.com"
target_domain: "example.com" # or example.net
# Optional explicit selectors:
source_account_id: "acc_id_1" # or source_account_name: "Client Org"
target_account_id: "acc_id_2" # or target_account_name: "Agency Org"Credentials and account selectors can also be provided via environment variables:
# For API Token:
export CLOUDFLARE_API_TOKEN="your_token_here"
# Or for Global API Key:
export CLOUDFLARE_API_KEY="your_global_key"
export CLOUDFLARE_EMAIL="your-email@example.com"
# Optional Account Selectors:
export CLOUDFLARE_SOURCE_ACCOUNT_ID="acc_id_source"
export CLOUDFLARE_TARGET_ACCOUNT_ID="acc_id_target"Note
All tokens, keys, and credentials are automatically redacted and are never printed, logged, or included in backup or report files.
When using a scoped Cloudflare API Token, create it at Cloudflare Dashboard -> My Profile -> API Tokens with the following permissions:
| Resource Scope | Permission | Required Access |
|---|---|---|
| All Zones / Specific Zones | Zone.Zone |
Read |
| Source Zone | Zone.Zone Settings, Zone.Rulesets, Zone.Workers Routes |
Read |
| Target Zone | Zone.Zone Settings, Zone.Rulesets, Zone.Workers Routes |
Edit (Read & Write) |
| Target Account (Optional) | Account.Workers Scripts |
Read (to validate Worker script bindings) |
- Cross-Account Migrations: The tool automatically discovers and validates source and target zones independently across separate Cloudflare accounts.
- Multiple Accounts for the Same Domain: If a domain (e.g.
example.com) exists in multiple Cloudflare accounts accessible by your credentials:- Interactive Prompt: The CLI automatically displays a list of discovered accounts in the terminal with account names, IDs, statuses, and plans, prompting you to choose which account to use.
- Config / CLI Flags: You can specify
source_account_id/target_account_id(or--source-account-id/--target-account-id) in non-interactive or automated workflows.
- Same-Domain Migration: Easily migrate configuration when transferring a domain between two Cloudflare accounts (source:
example.comin Account A -> target:example.comin Account B). - The source zone is strictly treated as READ-ONLY.
python3 cloudflare_clone.pyExecution steps:
- Validates
config.yaml. - Discovers Cloudflare Zone IDs, Account IDs, and statuses (prompts for selection if ambiguous).
- Verifies API permissions independently for source and target.
- Analyzes source & target configuration.
- Displays the comprehensive Migration Plan.
- Prompts for confirmation:
Apply these changes? [y/N]: - Takes a snapshot backup of the target zone.
- Applies changes safely to the target zone.
- Performs post-migration verification.
- Saves machine-readable report to
reports/YYYY-MM-DD_HH-MM-SS.json.
# Dry run: analyze and display plan without making any Cloudflare modifications
python3 cloudflare_clone.py --dry-run
# Automatically confirm and apply changes without prompt (useful for CI/CD)
python3 cloudflare_clone.py --yes
# Specify custom config file
python3 cloudflare_clone.py --config /path/to/custom-config.yaml
# Explicitly specify source and target accounts when ambiguous
python3 cloudflare_clone.py --source-account-id "acc_source_123" --target-account-id "acc_target_456"
# Or select by account name or zone ID
python3 cloudflare_clone.py --source-account-name "Primary Org" --target-account-name "Secondary Org"
python3 cloudflare_clone.py --source-zone-id "zone_src_id" --target-zone-id "zone_tgt_id"
# Enable verbose output
python3 cloudflare_clone.py --verboseThe tool uses the current official Cloudflare API v4 Rulesets Engine and Zone Settings:
- Origin Rules (
http_request_origin) - Cache Rules (
http_request_cache_settings) - Configuration Rules (
http_config_settings) - Redirect Rules (Single Dynamic Redirects:
http_request_dynamic_redirect) - Transform Rules:
- URL Rewrite (
http_request_transform) - Request Header Modification (
http_request_late_transform) - Response Header Modification (
http_response_headers_transform)
- URL Rewrite (
- WAF Custom Rules (
http_request_firewall_custom) - Rate Limiting Rules (
http_ratelimit) - Snippets Rules (
http_request_snippets) - Custom Error Responses (
http_custom_errors) - Workers Routes (Pattern transformation & script existence checks)
- Transferable Zone Settings:
- SSL/TLS mode (
ssl) - Always Use HTTPS (
always_use_https) - HTTP/2 (
http2) & HTTP/3 (http3) - WebSockets (
websockets) - Brotli Compression (
brotli) - HTML/CSS/JS Minification (
minify) - Rocket Loader (
rocket_loader) - Browser Cache TTL (
browser_cache_ttl) - Security Level (
security_level) - Challenge TTL (
challenge_ttl) - IP Geolocation (
ip_geolocation) - Email Obfuscation (
email_obfuscation) - Server Side Excludes (
server_side_exclude) - Hotlink Protection (
hotlink_protection) - 0-RTT Connection Resumption (
0rtt) - Early Hints (
early_hints) - TLS 1.3 (
tls_1_3) & Min TLS Version (min_tls_version) - Automatic HTTPS Rewrites (
automatic_https_rewrites) - Browser Integrity Check (
browser_check) - Privacy Pass (
privacy_pass)
- SSL/TLS mode (
To guarantee security and domain integrity, the following features are not transferred:
- DNS Records: Never modified or cloned (100% isolated).
- Custom Certificates & Edge Certificates: Bound to domain identity.
- Registrar & Nameservers: Tied to account and domain ownership.
- Account-level Managed WAF subscriptions & Billing tiers.
- Worker Scripts: Scripts must be deployed to the target account independently. If a Worker script is not found in the target account, the route is marked as
MANUAL ACTION REQUIRED.
DNS records are strictly untouched:
- Code-level blockers intercept and reject any mutation requests targeting DNS endpoints (
/dns_records,/custom_nameservers,/registrar). - Unit tests (
tests/test_dns_protection.py) explicitly verify that DNS cannot be modified under any circumstance. - Backup and reporting files strictly exclude DNS data.
Before any changes are applied to the target zone, a complete snapshot of its current transferable configuration is saved:
backups/YYYY-MM-DD_HH-MM-SS/target_backup.json
If an error occurs while applying a ruleset or updating a zone setting, the tool halts immediately and attempts to restore all previously modified settings and rulesets to their original state.
# Run all tests
pytest
# Run tests with coverage
pytest --cov=src --cov-report=term-missingMIT License. See LICENSE for details.