Skip to content

Basic Wrangler Extractor

Extract deployment topology from Cloudflare Workers configuration.

The basic-wrangler extractor analyzes wrangler.toml files to discover Workers, environments, service bindings, and infrastructure dependencies. It captures how your Workers deploy, not just what code they contain.


What It Extracts

From wrangler.toml files:

  • πŸ”Ή Containers β€” Cloudflare Workers as deployable units
  • πŸ”Ή Deployments β€” Environments (production, staging, preview)
  • πŸ”Ή Container Instances β€” Deployed instances per environment
  • πŸ”Ή Service Bindings β€” Worker-to-worker dependencies
  • πŸ”Ή Infrastructure Bindings β€” KV, R2, D1, Durable Objects, Queues
  • πŸ”Ή Relationships β€” Both logical (containerβ†’container) and physical (instanceβ†’instance)

Configuration

Basic Setup

extractors:
  - use: extractors/builtin/basic-wrangler
    inputs:
      include: ['wrangler.toml']

Multiple Workers

extractors:
  - use: extractors/builtin/basic-wrangler
    inputs:
      include:
        - 'workers/gateway/wrangler.toml'
        - 'workers/api/wrangler.toml'
        - 'workers/auth/wrangler.toml'

Monorepo Pattern

extractors:
  - use: extractors/builtin/basic-wrangler
    inputs:
      include: ['iac/workers/**/*.toml']
      exclude: ['**/wrangler.dev.toml']

What Gets Extracted

Containers

One per wrangler.toml file:

# workers/gateway/wrangler.toml
name = "bond-math-gateway"
main = "src/index.ts"
compatibility_date = "2024-01-01"

Becomes:

{
  "id": "bond-math-gateway",
  "name": "bond-math-gateway",
  "type": "Cloudflare Worker",
  "technology": "TypeScript",
  "layer": "Application",
  "tags": ["cloudflare-worker"]
}

Deployments & Environments

Extracts all environment configurations:

# Root level = production
name = "gateway"
main = "src/index.ts"

[env.development]
name = "gateway-dev"

[env.preview]
name = "gateway-preview"

Creates 3 deployments:

  • production (from root)
  • development
  • preview

Service Bindings

Worker-to-worker dependencies:

[[services]]
binding = "SVC_DAYCOUNT"
service = "bond-math-daycount"
environment = "production"

[[services]]
binding = "SVC_PRICING"
service = "bond-math-pricing"
environment = "production"

Creates:

  1. Logical relationship: gateway β†’ daycount
  2. Logical relationship: gateway β†’ pricing
  3. Physical relationship: productiongateway β†’ productiondaycount
  4. Physical relationship: productiongateway β†’ productionpricing

Infrastructure Bindings

KV Namespaces:

[[kv_namespaces]]
binding = "CACHE"
id = "abc123..."

R2 Buckets:

[[r2_buckets]]
binding = "DOCUMENTS"
bucket_name = "my-documents"

D1 Databases:

[[d1_databases]]
binding = "DB"
database_name = "production_db"
database_id = "xyz789..."

Durable Objects:

[[durable_objects.bindings]]
name = "RATE_LIMITER"
class_name = "RateLimiter"
script_name = "rate-limiter-worker"

Queues:

[[queues.producers]]
binding = "EVENTS"
queue = "event-queue"

All captured in container instance metadata.


Environment Overrides

Environment-specific configurations:

name = "gateway"
main = "src/index.ts"

[vars]
API_URL = "https://api.prod.example.com"
TIMEOUT = "30"

[env.development]
name = "gateway-dev"
vars = { API_URL = "https://api.dev.example.com", TIMEOUT = "5" }

[env.preview]
vars = { API_URL = "https://api.preview.example.com" }

Each environment instance gets correct vars:

  • production__gateway β†’ API_URL="https://api.prod..., TIMEOUT="30"
  • development__gateway β†’ API_URL="https://api.dev...", TIMEOUT="5"
  • preview__gateway β†’ API_URL="https://api.preview...", TIMEOUT="30"

Container Instance IDs

Simple pattern: {environment}__{service}

Worker Name Environment Instance ID
gateway production production__gateway
gateway development development__gateway
daycount production production__daycount
pricing-api staging staging__pricing-api

Why this pattern?

  • Simple and predictable
  • Easy to reference in other tools
  • No deep hierarchies
  • Scales to any number of services

Complete Example

wrangler.toml

name = "api-gateway"
main = "src/index.ts"
compatibility_date = "2024-01-01"

[vars]
LOG_LEVEL = "info"
INTERNAL_JWT_TTL = "90"

[[services]]
binding = "SVC_AUTH"
service = "auth-service"
environment = "production"

[[services]]
binding = "SVC_DATA"
service = "data-service"
environment = "production"

[[kv_namespaces]]
binding = "CACHE"
id = "abc123..."

[[r2_buckets]]
binding = "UPLOADS"
bucket_name = "user-uploads"

[env.development]
name = "api-gateway-dev"
vars = { LOG_LEVEL = "debug" }

[[env.development.services]]
binding = "SVC_AUTH"
service = "auth-service"
environment = "development"

[[env.development.services]]
binding = "SVC_DATA"
service = "data-service"
environment = "development"

Extracted Architecture

Containers (3):

  • api-gateway (Cloudflare Worker)
  • auth-service (inferred from binding)
  • data-service (inferred from binding)

Deployments (2):

  • production with 3 instances
  • development with 3 instances

Container Instances (6):

  • production__api-gateway (with CACHE KV, UPLOADS R2, SVC_AUTH, SVC_DATA)
  • production__auth-service
  • production__data-service
  • development__api-gateway (with SVC_AUTH, SVC_DATA)
  • development__auth-service
  • development__data-service

Logical Relationships (2):

  • api-gateway β†’ auth-service
  • api-gateway β†’ data-service

Physical Relationships (4):

  • productionapi-gateway β†’ productionauth-service
  • productionapi-gateway β†’ productiondata-service
  • developmentapi-gateway β†’ developmentauth-service
  • developmentapi-gateway β†’ developmentdata-service

Combining with Code Analysis

Use with basic-node for complete picture:

extractors:
  # Extract application code
  - use: extractors/builtin/basic-node
    inputs:
      include: ['src/**/*.ts']

  # Extract deployment topology
  - use: extractors/builtin/basic-wrangler
    inputs:
      include: ['wrangler.toml']

Result:

  • Components and actors from code annotations
  • Containers and deployments from wrangler config
  • Complete logical + physical architecture

Routes & Triggers

HTTP Routes:

routes = [
  { pattern = "api.example.com/*", zone_name = "example.com" }
]

Cron Triggers:

[triggers]
crons = ["0 0 * * *", "*/15 * * * *"]

Both captured in container instance metadata.


Observability

Logging and monitoring configuration:

[observability]
enabled = true
head_sampling_rate = 0.1

Captured as instance metadata.


Best Practices

βœ… Do

  • Keep wrangler.toml files discoverable β€” Use consistent naming
  • Document service bindings β€” Clear binding names help diagrams
  • Use environment overrides β€” Keep config DRY
  • Explicit environments β€” Define all environments you deploy to
  • Combine with code analysis β€” Use basic-node for complete view

❌ Don't

  • Spread configuration β€” Keep related workers in discoverable locations
  • Use cryptic names β€” SVC_1 worse than SVC_AUTH
  • Forget includes β€” Ensure patterns match your files
  • Mix production secrets β€” basic-wrangler extracts vars (use secrets for sensitive data)

Troubleshooting

Workers Not Showing Up

Check:

  1. wrangler.toml file has name field
  2. File matches include patterns
  3. File doesn't match exclude patterns
  4. TOML syntax is valid

Service Bindings Missing

Check:

  1. Using [[services]] array syntax
  2. binding and service fields present
  3. Service name matches target worker's name

Environments Not Created

Check:

  1. Using [env.environment_name] syntax
  2. Environment has deployable configuration (routes, vars, or bindings)
  3. Root level has content (implies production environment)

What's Next?

Combine with code:

Understand architecture:

Extend: