Edge-First Architecture
Dev, Staging, and Prod Validated

Edge-First Architecture with Cloudflare

Global iGaming Platform at <20ms Latency

The book's Brazilian betting platform now runs as a greenfield Cloudflare-native stack with isolated dev, staging, and prod environments. Workers handle compute, Durable Objects keep stateful game sessions, D1 stores read models, Queues move events, R2 holds audit artifacts, and Terraform workspaces keep each rollout isolated from the others.

Cloudflare Workers D1 SQLite KV Storage R2 Object Store Durable Objects Queues mTLS WAF Terraform
Cloudflare Deployment Surface

Chapter, lobby, and three games

The chapter page lives here on thebackendofluck.com/tech/cloudflare.html. The operational surface lives on cfgp.cloud-acmetocasino.com, which acts as the dedicated Cloudflare lobby for the three games listed below.

In the current production scope, these three games are 100% functional on the Cloudflare stack.

Request Flow

From chapter page to playable round

1. The player opens the Cloudflare lobby. Pages serves the lobby and the game shells directly from `cfgp.cloud-acmetocasino.com`.
2. The browser establishes a session. The frontend calls the Worker auth endpoint, which returns the token used by launch, balance, RNG, and betting flows.
3. Round state remains at the edge. Durable Objects maintain per-game session state for roulette, blackjack, and video poker while Workers expose the HTTP API used by the clients.
4. Read models and control functions stay on-platform. D1, KV, and the backoffice Worker expose balances, session control, reality-check state, and operational views without returning the player flow to the legacy stack.
5. The chapter documents the system. This page describes the architecture; the Cloudflare lobby exposes the running implementation.
Runtime Map

Current player-facing path

browser Cloudflare Pages lobby API Worker Durable Object game session D1 / KV / Queues / R2 backoffice read models

For the current scope, the player-facing core runs on Cloudflare for auth/session, launch, balance, rng, bet, and session-control enforcement.

3-Game Architecture

How roulette, blackjack, and video poker are arranged

The three games share the same session, launch, and control foundation, but each keeps its round state in its own runtime path.

Roulette Path

Launch → round → settlement

The player creates a session, launches roulette through the API Worker, and submits bets into the roulette runtime. Outcome, settlement, and balance refresh remain on the Cloudflare path while read-side state stays available for compliance and backoffice views.

Blackjack Path

Deal → action → final hand

Blackjack uses the same auth, wallet, and compliance layer, but preserves in-hand state in the blackjack runtime. Deal and action requests are resolved at the edge so that the core hand lifecycle does not depend on the legacy server.

Video Poker Path

Deal → draw → payout

Video poker reuses the same session and balance services, then routes round state into the video poker runtime for card dealing, draw resolution, and payout. The game loop remains on Cloudflare while still feeding compliance and operational read models.

What Changed

From Single Demo Stack to Environment-Aware Edge Platform

The current Cloudflare implementation is no longer just a chapter demo. It now has repeatable release automation, Pages deployment, end-to-end environment isolation, and an explicit operator runbook for shipping safely on the edge.

Architecture Delta

Greenfield stack isolated from the legacy domain

The new platform no longer reuses the legacy `new.acmetocasino.com` cutover path. It runs on dedicated Cloudflare-native hostnames under `cloud-acmetocasino.com`, with one Terraform workspace per environment and worker bindings synchronized to the real D1 and mTLS resources after provisioning.

dev → `cfgp-dev.cloud-acmetocasino.com`
staging → `cfgp-staging.cloud-acmetocasino.com`
prod → `cfgp.cloud-acmetocasino.com`
Release Pipeline

Provision, deploy, and verify in one path

The operator flow is now automated: Terraform apply, D1 id resolution, mTLS certificate creation or reuse, Wrangler binding sync, secret rotation, worker deploy, Pages lobby publish, and live verification against the public hostname plus the API and backoffice routes.

pnpm release:dev
pnpm release:staging
pnpm release:prod
End-to-End Tests

Smoke-tested against live Workers endpoints

Each environment is validated after deploy with a live sequence: public lobby fetch on `cfgp*.cloud-acmetocasino.com`, session creation, `roulette` launch in `BR/BRL`, API health, and backoffice compliance. This catches Pages misconfiguration, binding drift, and propagation issues immediately after rollout instead of after player traffic arrives.

Operational Lesson

Cloudflare account quotas are deployment dependencies

The rollout exposed two real platform constraints: D1 is capped per account, and Cloudflare Pages custom domains are not fixed by DNS alone. Before `prod` could be provisioned, one unused demo D1 had to be retired to free capacity. Later, the public hostnames returned `522` until the Pages domains were attached and the static lobby was actually deployed. The chapter now has a stronger lesson: on edge platforms, quota management and Pages release discipline are part of release engineering, not afterthoughts.

Infrastructure Inventory

What is actually running on the Cloudflare track

The current implementation is not a single Worker with static Pages around it. It is a multi-resource Cloudflare deployment where each platform service has a defined role in the release path and in the player-facing runtime.

Compute Plane

Pages and Workers

Cloudflare Pages serves the lobby and game shells. The API Worker handles session creation, launch, balance, RNG, betting, and routing into the game runtimes. The backoffice Worker exposes operational and compliance read paths.

State Plane

Durable Objects, D1, and KV

Durable Objects keep round and in-hand state for the games. D1 stores relational read-side state and operational records. KV is used for distributed session and cache responsibilities where edge read performance matters more than strict write coordination.

Storage and Events

R2 and Queues

R2 is used for platform artifacts and audit-side storage that does not belong in the relational model. Queues are used where the implementation needs deferred or decoupled work instead of extending the synchronous request path.

Control Plane

Terraform, Wrangler, and mTLS

Terraform provisions the environment-scoped resources, Wrangler binds Workers to the provisioned identifiers, and mTLS certificates are created or reused as part of the environment preparation sequence so that worker-to-service trust does not depend on manual setup.

Environment Topology

Three environments, one release shape

The Cloudflare path is structured so that `dev`, `staging`, and `prod` follow the same topology. The difference is the resource scope and hostname, not a separate architecture per environment.

Environment Lobby Host Primary Services Purpose
dev cfgp-dev.cloud-acmetocasino.com Pages lobby, API Worker, backoffice Worker, D1, KV, Durable Objects, mTLS Fast iteration, resource wiring checks, early functional validation
staging cfgp-staging.cloud-acmetocasino.com Same service set as dev with release rehearsal and public-path checks Pre-production validation, smoke tests, binding drift detection
prod cfgp.cloud-acmetocasino.com Pages lobby, API Worker, backoffice Worker, D1, KV, Durable Objects, mTLS Player-facing surface for the validated three-game Cloudflare path
mTLS and Binding Sync

What happens between provision and deploy

One of the main differences between the current Cloudflare track and the earlier chapter demo is that the deploy path now includes explicit post-provision synchronization. Provisioning the resources is not enough; the runtime must be rebound to the exact identifiers that Terraform created.

Operational Sequence
1. Terraform provisions the environment resources. This includes the Cloudflare-side objects that the workers and Pages deployment depend on.
2. D1 identifiers are resolved from Terraform state. The deploy path does not assume static values; it reads the provisioned identifiers back.
3. mTLS certificates are created or reused. That step is part of environment preparation, not a separate manual task after deployment.
4. Wrangler bindings are synchronized. The Worker configuration is updated to match the resources that actually exist in that environment.
5. Secrets and deploys happen only after the sync. That avoids deploying a Worker that points to stale or mismatched infrastructure.
Why It Matters

On this stack, the most common failure is not “the Worker code is wrong.” It is “the Worker code is correct, but the binding set points at the wrong D1 database, the wrong certificate context, or an incomplete environment.” The release path now treats binding synchronization as a first-class deployment step because Cloudflare environments are configuration-heavy and the runtime only behaves correctly when those identifiers match exactly.

terraform apply resolve D1 ids create or reuse mTLS sync Wrangler bindings rotate secrets deploy Workers and Pages
Release Sequence

The deploy path used for the current proof

The current Cloudflare release path is documented as an ordered sequence because changing the order changes the outcome. Deploying Pages before the domains are attached, or deploying Workers before bindings are synchronized, produces a superficially successful rollout with a broken public surface.

01

Provision

Select workspace and apply Terraform.

02

Prepare

Resolve D1 ids, mTLS, and environment bindings.

03

Deploy

Rotate secrets and deploy the Workers.

04

Publish

Publish the Pages lobby to the public hostname.

05

Verify

Run smoke and end-to-end checks against the live host.

Repository Commands
./scripts/deploy-workers.sh prod
./scripts/deploy-pages.sh prod
./scripts/smoke-test-cloudflare.sh prod
./scripts/e2e-cloudflare.sh prod
Validation and Failure Modes

What still breaks if release discipline slips

The current documentation now reflects the main operational lesson from the rollout: edge deployment failures are often successful deploys with incomplete public wiring. The checks below are the ones that matter because they catch that class of failure quickly.

Validation Checks
  • Public lobby fetch on the final hostname, not only on a Pages preview URL.
  • Session creation through the live API Worker.
  • Launch flow for at least one public game route.
  • Health verification for the Worker and the backoffice path.
  • End-to-end confirmation that the public domain resolves to the expected Cloudflare surface.
Observed Failure Modes
  • D1 quota exhaustion prevents provisioning even when the deploy scripts are correct.
  • Pages custom domains may still fail publicly after DNS is in place if the site has not been published to the attached domain.
  • Worker deploys can succeed while the runtime still points to stale bindings if the synchronization step is skipped.
  • Public previews can look correct while the production hostname still serves an older lobby version or returns `522`.
Resource Map by Environment

What each environment is expected to contain

The environment map is intentionally simple: each stage keeps the same release shape so that promotion does not change the architecture. In practice, the operator should be able to point at a hostname and know which Pages surface, Workers, bindings, and verification path belong to it.

dev

Fast iteration surface

  • Hostname: `cfgp-dev.cloud-acmetocasino.com`
  • Pages: lobby and game shells for early browser validation
  • Workers: API Worker and backoffice Worker with dev-scoped bindings
  • State: D1, KV, and Durable Objects for development traffic
  • Purpose: confirm resource wiring, session flow, and game-path behaviour before promotion
staging

Release rehearsal surface

  • Hostname: `cfgp-staging.cloud-acmetocasino.com`
  • Pages: public lobby path equivalent to production
  • Workers: staging API and backoffice runtime with synchronized bindings
  • State: staging D1, KV, Durable Objects, and certificate context
  • Purpose: dry-run the release path, verify domains, and catch binding or Pages drift before `prod`
prod

Player-facing surface

  • Hostname: `cfgp.cloud-acmetocasino.com`
  • Pages: official Cloudflare lobby for roulette, blackjack, and video poker
  • Workers: production API and backoffice Worker endpoints
  • State: production D1, KV, Durable Objects, queues, and mTLS-backed service path
  • Purpose: serve the validated three-game surface and the public operational path described in this chapter
Operator Rule

If an environment is missing any of the following, it is not ready to be treated as complete: attached Pages hostname, synchronized Worker bindings, D1 identifier resolution, active certificate path, and successful smoke or end-to-end verification against the public URL. That is the practical threshold between “resources exist” and “the environment is operational.”

Promotion Flow

Environment progression on the Cloudflare track

dev
Fast iteration
resource wiring
session flow
game-path checks
staging
Release rehearsal
binding sync
domain checks
smoke validation
prod
Player-facing surface
Pages lobby
3 live games
end-to-end verification
Why Cloudflare for iGaming

The Edge Advantage

Gambling platforms demand low latency (players notice 100ms), DDoS resilience (constant target), global reach, and strict compliance. Cloudflare's platform addresses all four simultaneously.

bolt

Edge Computing

300+ cities. Workers run at the PoP closest to the player, not in a US-East datacenter. Brazilian players connect to Cloudflare's São Paulo or Fortaleza edge, achieving <5ms network hop.

shield

DDoS Protection

iGaming platforms are attacked during peak betting events (finals, jackpots). Cloudflare absorbs volumetric attacks at the network layer before a single packet reaches the origin.

terminal

Workers Serverless

TypeScript Workers handle the API gateway, rate limiting, player routing, and game session management. No cold starts, isolate-based execution — not Node.js containers.

storage

D1 Edge Database

SQLite at the edge. The wallet and player session tables live in D1, replicated globally. Event-sourced transactions ensure the balance is always consistent across replicas.

key

KV for Sessions

Player JWTs, rate limit counters, and game state are stored in Cloudflare KV. Globally consistent reads with eventual consistency writes — perfect for session data at scale.

security

WAF & Bot Management

Bot score <30 blocks bet placement. WAF rules enforce IP allowlists for internal APIs. Managed rulesets cover OWASP Top 10 without any origin-side configuration.

Architecture

Request Flow: Browser to Edge to Origin

Player
Browser
Brazil / Global
Edge
Cloudflare
300+ PoPs · DDoS · WAF
Compute
Workers
TypeScript · No cold start
→ D1 → KV → R2
D1 Wallet DB
KV Sessions
R2 Game Assets
Origin
AcmeToCasino
Backend API
Cache HIT: <5ms Worker compute: <10ms Origin fallback: <80ms
Real Examples from the Book

Production Workers & Terraform

01

Casino API Gateway Worker

The entry-point Worker handles rate limiting per player, routes requests to game or wallet services, and falls back to static assets. The rate limiter uses KV as a distributed counter with a 120-second TTL — no Redis, no external service.

workers/casino-gateway/src/index.ts
// Cloudflare Worker: Casino API Gateway
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);

    // Rate limiting per player
    const playerId = request.headers.get('X-Player-ID');
    const rateKey = `rate:${playerId}:${Math.floor(Date.now() / 60000)}`;
    const count = await env.KV.get(rateKey) || '0';

    if (parseInt(count) > 100) {
      return new Response('Rate limited', { status: 429 });
    }
    await env.KV.put(rateKey, String(parseInt(count) + 1), { expirationTtl: 120 });

    // Route to game services
    if (url.pathname.startsWith('/api/gal/')) {
      return handleGAL(request, env);
    }
    if (url.pathname.startsWith('/api/wallet/')) {
      return handleWallet(request, env);
    }

    return env.ASSETS.fetch(request);
  }
};
02

D1 Wallet with Event Sourcing

The wallet uses an event-sourced model in D1: deposits, wins, bets, and withdrawals are all immutable events. The current balance is derived by summing events — no mutable balance column that could go out of sync. This satisfies both ACID guarantees and the audit trail requirements of Brazilian gambling regulation.

workers/casino-gateway/src/wallet.ts
// D1 Database: Player wallet with event sourcing
async function handleWallet(request: Request, env: Env): Promise<Response> {
  const { player_id, amount, type } = await request.json();

  // Event-sourced transaction
  const result = await env.DB.prepare(`
    INSERT INTO wallet_events (player_id, event_type, amount, created_at)
    VALUES (?, ?, ?, datetime('now'))
    RETURNING (
      SELECT COALESCE(SUM(
        CASE WHEN event_type = 'DEPOSIT' THEN amount
             WHEN event_type = 'WIN' THEN amount
             ELSE -amount END
      ), 0) FROM wallet_events WHERE player_id = ?
    ) as new_balance
  `).bind(player_id, type, amount, player_id).first();

  return Response.json({ balance: result.new_balance });
}
03

WAF Rules via Terraform

All Cloudflare configuration is managed through Terraform — including WAF rules. This ensures changes are reviewed in pull requests, rolled back if needed, and logged in the audit trail. The two rules shown block direct API access from non-whitelisted IPs and prevent bot-generated bets (Cloudflare's bot score 0–100).

terraform/cloudflare/waf.tf
# Terraform: Cloudflare WAF for gambling compliance
resource "cloudflare_ruleset" "casino_waf" {
  zone_id = var.zone_id
  name    = "Casino WAF Rules"
  kind    = "zone"
  phase   = "http_rq_firewall_managed"

  rules {
    action = "block"
    expression = "(http.request.uri.path contains \"/api/\" and not ip.src in {10.0.0.0/8})"
    description = "Block direct API access from non-whitelisted IPs"
  }

  rules {
    action     = "block"
    expression = "(cf.bot_score lt 30 and http.request.uri.path contains \"/api/gal/bet\")"
    description = "Block bot betting attempts"
  }
}
In the Book

Chapters Covering Cloudflare

Ch. 44
Cloudflare Workers

Deploying on Cloudflare Workers

Full migration of the casino backend to Workers: TypeScript Worker setup, Wrangler config, D1 schema, KV namespaces, and R2 bucket binding. Includes latency benchmarks vs. origin-only deployment.

Workers Wrangler D1
Ch. 44b
Hybrid Runtime

Hybrid Runtime Architecture

Not everything belongs at the edge. Chapter 44b covers the decision framework: what stays in Workers (routing, sessions, simple queries) vs. what goes to origin (RNG, HSM operations, complex game logic).

Hybrid Origin Architecture
Ch. 46
Brazil Platform

Brazilian Betting Platform

End-to-end deployment of the Brazilian sports betting platform on Cloudflare, including PIX payment integration, SIGAP regulatory reporting from the edge, and geo-restriction rules enforcing Brazilian-only access.

Brazil PIX SIGAP
Compliance at the Edge

Zone Control & Jurisdiction Management

Gambling is regulated per jurisdiction. Cloudflare's edge network enforces geo-restrictions, content rules, and regulatory requirements before traffic reaches the origin — at the network level, not the application level.

public

Geo-Restriction

Block or allow traffic by country at the edge. Brazilian platform restricts to BR-only. MGA license serves EU. UKGC serves GB. Cloudflare evaluates ip.geoip.country before the request reaches any backend.

expression = "ip.geoip.country ne \"BR\""
action = "block"
# Brazilian platform: block all non-BR traffic
gavel

Multi-Jurisdiction

Different DNS zones serve different regulated markets. Each zone has its own WAF rules, rate limits, and compliance headers. One Cloudflare account manages all jurisdictions.

Brazil — bet-brazil.cloud-acmetocasino.com — SIGAP, Lei 14.790
Malta/EU — casino.cloud-acmetocasino.com — MGA, GDPR
UK — Separate zone — UKGC, GamStop
Curaçao — Separate zone — GCB license
US (regulated states) — Per-state zones — NJ, MI, PA, WV
shield

Compliance Headers

Each jurisdiction requires specific HTTP headers, cookie policies, and content restrictions. Cloudflare Transform Rules inject the right headers per zone — no application code changes needed.

# Brazil zone headers
X-Jurisdiction: BR
X-License: SPA-MF/2025
X-RG-Required: true
X-Age-Minimum: 18
X-Currency: BRL

Jurisdiction Matrix — Managed via Cloudflare Zones

Jurisdiction Regulator Geo-Rule Data Residency Currency Status
BrazilSPA-MF (Ministério da Fazenda)BR onlyBrazil (LGPD)BRLLive
Malta / EUMGAEU/EEAEU (GDPR)EURLive
United KingdomUKGCGB onlyUKGBPPlanned
CuraçaoGCBGlobal (excl. blocked)CaribbeanUSDPlanned
US — New JerseyDGENJ only (GPS)US (NJ)USDReference
SwedenSpelinspektionenSE onlyEU (GDPR)SEKPlanned
DenmarkSpillemyndighedenDK onlyEU (GDPR)DKKPlanned

Each jurisdiction runs as an independent Cloudflare zone with its own DNS, WAF rules, and compliance configuration. Covered in Chapters 6, 29, and 40.

Full Source Included

All the Workers. All the Terraform. All 47 Chapters.

Every Worker, D1 schema, Terraform module, and Wrangler config from the book's reference platform is included with purchase — ready to deploy to your own Cloudflare account.