Skip to content

Cloudflare Migration Runbook

Cloudflare Account Bootstrap, Migration & Platform Provider Runbook

1. Executive Summary & Migration Topology

This operational runbook governs the migration and bootstrapping of SiteSwarm infrastructure from the founder’s legacy personal Cloudflare account (jacobmiller22.com) to the dedicated corporate business account (JP Technology Solutions / Jpsoftwareassociates@gmail.com's Account).

Migrating to the corporate account establishes an isolated, enterprise-grade production environment for SiteSwarm applications, client tenant instances, and shared platform services, decoupling commercial assets from personal credentials and ensuring seamless operational scalability.

flowchart TD
subgraph LegacyAccount["Legacy Personal Account (jacobmiller22.com)"]
LegacyDNS["Personal Zone: jacobmiller22.com\n(Apex, Portfolio, Dev Services)"]
LegacyD1["Legacy D1 Databases\n(inquiries, clk-cms)"]
LegacyWorkers["Legacy Workers Subdomain\n(*.jacobmillerdev.workers.dev)"]
end
subgraph CorporateAccount["Corporate Account (JP Technology Solutions - 7fba1ed07b005a3c31a890fe6c20cda2)"]
CorpZone["Authoritative Zone: jpsoftwareassociates.com\n(Zone ID: 4dfdcba71d71e6a0bbf0af0015c77233)"]
CorpPlan["Workers Paid Plan\n• Extended CPU & Unbound Mode\n• Outbound Authenticated SMTP\n• Browser Rendering CDP"]
CorpSub["Corporate Subdomain\n(*.jpsoftwareassociates.workers.dev)"]
CorpStorage["Production State\n• D1: siteswarm-production-db\n• KV: watchdog-state\n• R2: siteswarm-demos, client-media"]
SecProfile["Baseline Security\n• Full (strict) TLS\n• Universal SSL (*.jpsoftwareassociates.com)\n• Always Use HTTPS (301)\n• DNSSEC Active"]
end
subgraph DualTierSecurity["Dual-Tier API Token Security Matrix"]
DevToken["Local Developer Token\n(Elevated Scope: Interactive Debugging & Init)"]
CIToken["CI/CD Pipeline Token\n(Least-Privilege Scoped: Deploy, D1, KV, Routes)"]
end
LegacyAccount -.->|"Phased Cutover & Re-pointing"| CorporateAccount
DualTierSecurity -->|"Automated GitHub Actions"| CorporateAccount

2. Legacy Account Resource Audit & Inventory (jacobmiller22.com)

An exhaustive audit of account-level and zone-level assets on the legacy personal Cloudflare account was conducted to map all dependencies requiring replication or migration.

2.1 Account Profile & Subscription Comparison

Attribute / Capability Legacy Personal Account Target Corporate Account Operational Impact
Account Name jacobmiller22.com (Personal) Jpsoftwareassociates@gmail.com's Account Enterprise organizational identity
Account ID jacobmillerdev personal ID 7fba1ed07b005a3c31a890fe6c20cda2 Master CLOUDFLARE_ACCOUNT_ID update
Workers Plan Workers Free / Legacy Paid workers_paid Unlocked script count, Unbound CPU (up to 30s)
Workers Subdomain jacobmillerdev.workers.dev jpsoftwareassociates.workers.dev Canonical platform script URL suffix
Email Service Restricted / Third-party email_service_emails_sent active Native authenticated SMTP (smtp.mx.cloudflare.net:465)
Browser Rendering Ad-hoc / Free allocation browser_rendering_total_browser_hours Deterministic CDP demo capture & visual regression
Queues & Workflows Unverified / Partial queues_enabled, workflows_enabled Asynchronous event processing platform

2.2 Authoritative Zones & Hostname Ingress

Zone / Hostname Legacy Configuration Corporate Target Configuration Cutover Protocol
jacobmiller22.com Primary platform zone hosting portfolio, staging apps, fallback ingress, and services Remains personal zone; serves founder portfolio (apps/me-portfolio) Retain personal records; migrate platform service subdomains
jpsoftwareassociates.com Not present on personal account Primary corporate zone (4dfdcba71d71e6a0bbf0af0015c77233) Active zone onboarded via Cloudflare Registrar
siteswarm.dev Secondary marketing zone Transfer / configure under corporate account Re-point apps/marketing production routes
Fallback Origin fallback.jacobmiller22.com (192.0.2.1 proxied A record) fallback.jpsoftwareassociates.com (100:: proxied AAAA record) RFC 6666 discard prefix anchor for Custom Hostnames
Platform Services inquiries.jacobmiller22.com, critique.jacobmiller22.com, command-center.jacobmiller22.com inquiries.jpsoftwareassociates.com, critique.jpsoftwareassociates.com, command-center.jpsoftwareassociates.com Re-bind routes in services/*/wrangler.jsonc
Client Domains Custom hostnames mapped to personal fallback Custom hostnames mapped to fallback.jpsoftwareassociates.com Dual-route ingress (<client>-ingress.jpsoftwareassociates.com)

2.3 Stateful Storage & Database Instances

Subsystem Legacy Instance Names Corporate Target Instances Migration Seam
D1 SQL Databases siteswarm-inquiries-db
siteswarm-inquiries-staging-db
clk-construction-cms-prod-d1
clk-construction-cms-staging-d1
siteswarm-inquiries-prod-db
siteswarm-inquiries-staging-db
clk-construction-cms-prod-db
clk-construction-cms-staging-db
siteswarm-production-db
siteswarm-staging-db
Export schema + data via wrangler d1 export, import into new corporate D1 instances via wrangler d1 execute
KV Namespaces watchdog-state
watchdog-state-staging
*-session (PR previews)
watchdog-state
watchdog-state-staging
*-session
Re-create namespaces via wrangler kv:namespace create; update UUID bindings in wrangler.jsonc
R2 Storage Buckets siteswarm-demos
green-leaf-bakery-media-*
clk-construction-media-*
siteswarm-demos
green-leaf-bakery-media-prod
clk-construction-media-prod
Create buckets on corporate account; sync existing demo and media objects via rclone or AWS S3 CLI

2.4 Worker Applications & Platform Services Catalog

All 11 applications and 6 platform services must deploy cleanly to the target corporate account:

  • Client & Edge Applications (apps/*):
    • apps/auto-repair (siteswarm-app-auto-repair)
    • apps/bakery (green-leaf-bakery)
    • apps/clk-construction (clk-construction)
    • apps/clk-construction-cms (clk-construction-cms)
    • apps/command-center (siteswarm-command-center)
    • apps/docs (siteswarm-app-docs)
    • apps/marketing (siteswarm-marketing)
    • apps/me-portfolio (me-portfolio)
    • apps/rcc-stjohn (rcc-stjohn)
    • apps/rcc-stpatrick (rcc-stpatrick)
    • apps/rcc-stpeter (rcc-stpeter)
    • apps/software-agency (apex-labs)
  • Platform Microservices (services/*):
    • services/cache-purge (siteswarm-cache-purge)
    • services/critique (siteswarm-service-critique)
    • services/email-sender (siteswarm-email-sender)
    • services/event-platform (siteswarm-event-platform)
    • services/inquiries (siteswarm-service-inquiries)
    • services/watchdog (siteswarm-service-watchdog)

2.5 Manual Dashboard-Only Configurations (Pre-Deployment Checklist)

The following configurations cannot be provisioned purely via Wrangler scripts and must be enabled in the Cloudflare Dashboard prior to running CI pipelines:

  1. R2 Subscription Activation Toggle: Navigate to Storage & Databases > R2 in the corporate account dashboard and enable the R2 service.
  2. Workers AI & Browser Rendering Allocation: Ensure the Browser Rendering feature is toggled on under Compute (Workers) > Browser Rendering to allocate headless browser hours for CDP screencast automation.
  3. Turnstile Site & Secret Key Generation: Under Security > Turnstile, generate managed bot protection keys for jpsoftwareassociates.com and client staging origins.
  4. Cloudflare Zero Trust Organization: Verify the Zero Trust team domain (e.g. siteswarm.cloudflareaccess.com) and configure Access applications for internal tools (command-center).

3. Fresh Corporate Account Bootstrap Protocol

Follow these procedural steps to initialize the target corporate account from zero:

Step 1: Corporate Profile & Billing Initialization

  1. Register/confirm account under corporate organization credentials (Jpsoftwareassociates@gmail.com).
  2. Record the unique Account ID:
    Terminal window
    CLOUDFLARE_ACCOUNT_ID="7fba1ed07b005a3c31a890fe6c20cda2"
  3. Set up organizational billing details and payment profiles.

Step 2: Workers Paid Plan Enrollment

  1. Navigate to Compute (Workers) > Plans and enroll in Workers Paid (rate_plan.id: "workers_paid").
  2. Verify active subscription entitlements:
    Terminal window
    curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/subscriptions" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq -r '.result[] | .rate_plan.public_name'
    # Expected Output: Workers Paid

Step 3: Corporate workers.dev Subdomain Provisioning

  1. Set the corporate subdomain to jpsoftwareassociates:
    Terminal window
    curl -s -X PUT "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/subdomain" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data '{"subdomain":"jpsoftwareassociates"}'
  2. Confirm the corporate subdomain is active:
    Terminal window
    curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/subdomain" \
    -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" | jq -r '.result.subdomain'
    # Output: jpsoftwareassociates

Step 4: Primary Domain Registration & Zone Onboarding

  1. Register jpsoftwareassociates.com via Cloudflare Registrar or onboard as an authoritative DNS zone.
  2. Confirm Zone ID and Authoritative Nameservers:
    • Zone ID: 4dfdcba71d71e6a0bbf0af0015c77233
    • Authoritative Nameservers: trace.ns.cloudflare.com, zara.ns.cloudflare.com

Step 5: Baseline Security Profile Configuration

Enforce the mandatory platform security baseline on zone 4dfdcba71d71e6a0bbf0af0015c77233:

Terminal window
ZONE_ID="4dfdcba71d71e6a0bbf0af0015c77233"
# 1. Enforce Full (strict) SSL/TLS encryption
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/ssl" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"strict"}'
# 2. Enforce Always Use HTTPS (301 redirect)
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/always_use_https" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value":"on"}'
# 3. Enable DNSSEC
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dnssec" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"status":"active"}'

Step 6: Core Resource Provisioning Commands

Provision core D1 databases, KV namespaces, R2 buckets, and fallback DNS records:

Terminal window
# --- D1 Database Provisioning ---
npx wrangler d1 create siteswarm-inquiries-prod-db
npx wrangler d1 create siteswarm-inquiries-staging-db
npx wrangler d1 create clk-construction-cms-prod-db
npx wrangler d1 create clk-construction-cms-staging-db
npx wrangler d1 create siteswarm-production-db
npx wrangler d1 create siteswarm-staging-db
# Note: Record the database_id UUIDs and update the binding tables in apps/*/wrangler.jsonc
# and services/*/wrangler.jsonc.
# --- KV Namespace Provisioning ---
npx wrangler kv:namespace create "WATCHDOG_STATE"
npx wrangler kv:namespace create "WATCHDOG_STATE" --env staging
# --- R2 Bucket Provisioning ---
npx wrangler r2 bucket create siteswarm-demos
npx wrangler r2 bucket create green-leaf-bakery-media-prod
npx wrangler r2 bucket create clk-construction-media-prod
# --- Fallback Origin DNS Record for Cloudflare for Platforms ---
# Creates an Orange-Cloud Proxied AAAA record pointing to RFC 6666 IPv6 discard prefix (100::)
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"type": "AAAA",
"name": "fallback",
"content": "100::",
"ttl": 1,
"proxied": true,
"comment": "Cloudflare for Platforms Custom Hostnames Fallback Origin"
}'
# --- Fallback Origin Custom Hostnames Setting ---
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames/fallback_origin" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"origin":"fallback.jpsoftwareassociates.com"}'

4. Dual-Tier API Token Security Matrix

To prevent privilege escalation and protect corporate infrastructure, credentials are bifurcated into an elevated local developer tier and a strictly scoped, least-privilege CI/CD tier.

4.1 Security Invariant: Local Developer vs. CI/CD Isolation

  • Tier 1: Local Developer Access:
    • Authenticated via interactive npx wrangler login (OAuth authorization) or elevated personal tokens with user confirmation.
    • Granted broad administrative permissions for rapid debugging, initial resource provisioning, and schema experimentation.
    • Restricted to trusted developer workstations; never committed to version control or hardcoded in scripts.
  • Tier 2: CI/CD Pipeline Automation (GitHub Actions):
    • Scoped strictly to the least-privilege permissions required to build, test, and deploy Workers, update D1 schemas, bind KV/R2, and purge cache.
    • Stored in GitHub Environment Secrets (staging and production), isolated from ephemeral PR previews.
    • Zero Superadmin / Account-Owner Rights: Explicitly forbidden from user management, billing, zone deletion, or audit log manipulation.

4.2 Permission Specification Matrix

Permission Category Scope Name Local Developer Token CI/CD Pipeline Token Justification / Operational Seam
Workers Scripts Account > Workers Scripts:Edit ✅ Granted ✅ Granted Required to compile, upload, and deploy Worker script bundles.
Workers Routes Zone > Workers Routes:Edit ✅ Granted ✅ Granted Required to attach custom domain routes to deployed Workers.
Workers KV Storage Account > Workers KV Storage:Edit ✅ Granted ✅ Granted Required for session management and watchdog state.
D1 SQL Database Account > D1:Edit ✅ Granted ✅ Granted Required to run migration schemas (schema.sql) and read query status.
R2 Storage Account > Workers R2 Storage:Edit ✅ Granted ✅ Granted (or Bucket-scoped) Required to store demo screencasts (siteswarm-demos) and client media.
Browser Rendering Account > Browser Rendering:Edit ✅ Granted ✅ Granted Required for Playwright remote CDP connection during acceptance tests.
Custom Hostnames Zone > SSL and Certificates:Edit ✅ Granted ✅ Granted Required to create and manage client custom hostnames and DCV checks.
Zone Cache Purge Zone > Cache Purge:Purge ✅ Granted ✅ Granted Required for cache invalidation on deployment and content updates.
Account Settings Account > Account Settings:Read ✅ Granted ✅ Granted (Read-Only) Required for Wrangler account verification (wrangler whoami).
Zone Settings Zone > Zone Settings:Read ✅ Granted ✅ Granted (Read-Only) Required to verify SSL encryption mode and HTTPS redirection.
DNS Records Zone > DNS:Edit ✅ Granted ❌ DENIED (IaC / Dev only) Zone apex DNS records managed via Terraform or local admin; CI cannot delete DNS.
Zero Trust / Access Account > Access: Apps and Policies:Edit ✅ Granted ❌ DENIED CI pipelines do not mutate Zero Trust security policies.
User & Membership Account > Members:Edit ❌ Denied (Owner only) ❌ DENIED Prevents compromised CI from adding rogue administrators.
Billing & Invoicing Account > Billing:Edit ❌ Denied (Owner only) ❌ DENIED Billing details isolated from developer and CI tokens.
Zone Lifecycle Zone > Zone:Edit / Delete ❌ Denied (Owner only) ❌ DENIED Protects corporate zones against accidental or malicious deletion.

4.3 GitHub Environment Secret Scoping

To eliminate flat repository-level secret inheritance:

flowchart TD
subgraph RepoLevel["Repository-Level Secrets (Safe Defaults)"]
CLOUDFLARE_ACCOUNT_ID["CLOUDFLARE_ACCOUNT_ID: 7fba1ed07b005a3c31a890fe6c20cda2"]
end
subgraph StagingEnv["GitHub Environment: staging"]
STG_TOKEN["CLOUDFLARE_API_TOKEN (Staging Token)\nScoped to: *-staging Workers & Databases"]
STG_CC_TOKEN["COMMAND_CENTER_CLOUDFLARE_API_TOKEN\n(Read-Only Analytics)"]
end
subgraph ProdEnv["GitHub Environment: production"]
PROD_TOKEN["CLOUDFLARE_API_TOKEN (Production Token)\nScoped to: Production Workers, Zones & DBs"]
PROD_CC_TOKEN["COMMAND_CENTER_CLOUDFLARE_API_TOKEN\n(Read-Only Analytics)"]
end
RepoLevel --> StagingEnv
RepoLevel --> ProdEnv

4.4 Anti-Leakage & Token Storage Invariants

  1. Encrypted Worker Secrets vs. Plaintext vars:
    • API tokens and bearer credentials must never be injected into plaintext vars in wrangler.jsonc or build artifacts.
    • Always provision secrets at runtime using encrypted Worker Secrets (npx wrangler secret put <SECRET_NAME>).
  2. Zero Ambient Fallback to Test Keys in Production:
    • Application code must never fall back to test tokens (e.g. Cloudflare Turnstile ALWAYS_PASSES key 1x0000000000000000000000000000000AA) in staging or production environments; missing secrets must fail closed.

5. Cutover, Verification & Rollback Protocol

5.1 Pre-Flight Verification Checklist

Before initiating production traffic cutover:

  • Account ID 7fba1ed07b005a3c31a890fe6c20cda2 verified active with workers_paid rate plan.
  • Corporate subdomain jpsoftwareassociates.workers.dev responding.
  • Zone jpsoftwareassociates.com (4dfdcba71d71e6a0bbf0af0015c77233) active with Full (strict) TLS and Always Use HTTPS.
  • Universal SSL certificate pack issued and active for jpsoftwareassociates.com and *.jpsoftwareassociates.com.
  • Fallback origin fallback.jpsoftwareassociates.com (100:: proxied) registered under Custom Hostnames.
  • D1 production databases seeded and schema migrations applied.
  • Dual-Tier CI/CD API token generated and configured in GitHub Environment Secrets.

5.2 Cutover Execution Sequence

  1. Deploy Services to Corporate Account:
    • Deploy services/inquiries, services/cache-purge, and services/watchdog to corporate Cloudflare account.
  2. Deploy Applications with Dual-Route Ingress:
    • Deploy apps/marketing to jpsoftwareassociates.com.
    • Deploy client applications (apps/bakery, apps/auto-repair, etc.) to corporate account with dual-route bindings (<client>-ingress.jpsoftwareassociates.com and client custom domains).
  3. Migrate CNAME Targets at External Registrars:
    • Update client DNS CNAME records from legacy targets (<client>-ingress.jacobmiller22.com) to corporate targets (<client>-ingress.jpsoftwareassociates.com).
  4. Purge Edge Cache:
    • Trigger cache invalidation across all zones via services/cache-purge.

5.3 Post-Cutover Behavioral Runtime Smoke Tests

Execute Tier 2 behavioral checks against the production edge:

Terminal window
# 1. Attest HTTPS redirect and strict TLS on corporate domain
curl -I http://jpsoftwareassociates.com
# Expected: HTTP/1.1 301 Moved Permanently -> Location: https://jpsoftwareassociates.com/
curl -I https://jpsoftwareassociates.com
# Expected: HTTP/2 200 OK (with Cloudflare cf-ray header)
# 2. Attest Fallback Origin resolves to Cloudflare edge anycast
dig AAAA fallback.jpsoftwareassociates.com +short @1.1.1.1
# Expected: Cloudflare Anycast IPv6 addresses (proxied)
# 3. Attest Platform Inquiries API Health
curl -s https://inquiries.jpsoftwareassociates.com/health | jq .
# Expected: {"status":"healthy"}
# 4. Execute E2E Playwright Suite against Corporate Endpoints
pnpm run test:e2e

5.4 Rollback & Emergency Contingency Protocol

If edge routing failures, SSL certificate generation delays, or fatal database connectivity issues occur during cutover:

  1. Custom Hostname Ingress Rollback: Revert client registrar CNAME records to point back to legacy target (<client>-ingress.jacobmiller22.com).
  2. Worker Fallback Routing: Retain legacy Worker instances running on jacobmillerdev.workers.dev in standby for 72 hours post-cutover.
  3. Database Read-Replica Sync: Maintain asynchronous transaction logs to re-apply any inquiries or state captured during cutover back to the legacy database if rollback is required.

6. Platform Provider Documentation Architecture

To ensure consistency across external platform and infrastructure integrations, SiteSwarm enforces a standardized 3-tier documentation paradigm under docs/runbooks/ and docs/architecture/.

6.1 Standardized Provider Documentation Structure

Whenever an external service or cloud provider is integrated into SiteSwarm (e.g. Cloudflare, GitHub, Stripe, Resend, BetterStack), the integration must be documented according to the following standard file topology:

docs/
├── architecture/
│ └── <PROVIDER>_PLATFORM_INTEGRATION.md # Architectural design, threat model, and topology
└── runbooks/
├── <PROVIDER>_ACCOUNT_CAPABILITIES.md # Active subscription plans, limits, and quotas
├── <PROVIDER>_MIGRATION_RUNBOOK.md # Provisioning, bootstrap, and cutover protocols
└── <PROVIDER>_CREDENTIALS_AND_SECURITY.md # Token scopes, rotation, and secret matrices

6.2 Provider Onboarding Requirements

Every platform provider runbook must satisfy:

  1. Domain Separation Invariant: Hardcoding retail subscription prices ($/mo) or commercial retainers is strictly prohibited; specs document capability IDs, rate plans, and technical quotas only.
  2. Anti-Mocking Runtime Commands: All runbooks must provide copy-paste CLI verification commands (curl, wrangler, dig) demonstrating real behavioral outputs.
  3. Decisions Intentionally Deferred: Explicitly list out-of-scope items to prevent scope inflation and preserve Minimal Viable Abstraction (MVA).
  4. Architectural Linter Compliance: All documents must conform to the 4-pillar taxonomy (docs/{architecture,runbooks,business,write-ups}) enforced by pnpm run lint:arch.

7. Decisions Intentionally Deferred

The following architectural and operational decisions are intentionally deferred to subsequent milestones:

  • Live DNS Production Cutover Execution: The physical modification of production DNS records for live commercial clients will occur in coordinated follow-up client onboarding stories.
  • Enterprise Infrastructure-as-Code (Terraform) Orchestration: Account-level bootstrapping is currently standardized using declarative Wrangler commands and audited dashboard steps (MVA) before introducing Terraform enterprise state orchestration.
  • Advanced Certificate Manager Add-On: Retaining single-level hyphenated subdomains (<app>-preview.jpsoftwareassociates.com) within standard Universal SSL rather than purchasing paid multi-level ACM certificate packs.
  • Subdomain Taxonomy for Future Commercial Client White-Labeling: Multi-tier subdomain isolation for white-label reseller clients will be evaluated in subsequent platform epics.