bitcain docs
Infrastructure

cloudflare

Requirements

The following requirements are needed by this module:

Providers

The following providers are used by this module:

Modules

No modules.

Resources

The following resources are used by this module:

Required Inputs

The following input variables are required:

account_id

Description: Cloudflare Account ID

Type: string

api_token

Description: Cloudflare API token with appropriate permissions

Type: string

environment

Description: Environment (dev, production)

Type: string

zone_id

Description: Cloudflare Zone ID for bitcain.net

Type: string

Optional Inputs

The following input variables are optional (have default values):

cf_access_admin_groups

Description: Google Workspace/Entra groups allowed admin access (for future scaling)

Type: list(string)

Default: []

cf_access_allow_domain

Description: Allow all users from @bitcain.net domain (for when you hire employees)

Type: bool

Default: false

cf_access_allowed_emails

Description: List of email addresses allowed to access protected applications

Type: list(string)

Default: []

cf_access_enable_service_token

Description: Create service token for CI/CD automated access

Type: bool

Default: false

cf_access_enabled

Description: Enable Cloudflare Zero Trust Access for protected applications

Type: bool

Default: false

cf_access_entra_client_id

Description: Entra ID application (client) ID for Cloudflare Access OIDC

Type: string

Default: ""

cf_access_entra_client_secret

Description: Entra ID client secret for Cloudflare Access OIDC

Type: string

Default: ""

cf_access_entra_enabled

Description: Enable Microsoft Entra ID as identity provider for Cloudflare Access

Type: bool

Default: false

cf_access_entra_tenant_id

Description: Entra ID tenant ID for Cloudflare Access OIDC

Type: string

Default: ""

cf_access_session_durations

Description: Session duration overrides per application type

Type:

object({
    admin  = optional(string, "1h")
    portal = optional(string, "8h")
    health = optional(string, "4h")
    api    = optional(string, "1h")
  })

Default: {}

custom_domains

Description: Custom domain configurations beyond default services

Type:

map(object({
    subdomain = string
    target    = string
    type      = optional(string, "CNAME")
    ttl       = optional(number, 300)
    proxied   = optional(bool, true)
    priority  = optional(number)
  }))

Default: {}

email_provider

Description: Email provider for MX/SPF/DKIM/DMARC records. Use microsoft_365_migration during cutover (keeps both SPF includes).

Type: string

Default: "none"

health_checks

Description: Configuration for health checks. Default disabled — each check wakes Cloud Run.

Type:

object({
    enabled             = optional(bool, false)
    regions             = optional(list(string), ["WNAM"])
    interval            = optional(number, 900) # 15 min — never use 60s, it keeps Cloud Run warm 24/7
    timeout             = optional(number, 10)
    retries             = optional(number, 2)
    notification_emails = optional(list(string), [])
  })

Default: {}

kv_namespaces

Description: Additional KV namespaces to create

Type:

map(object({
    title = string
  }))

Default: {}

network_config

Description: Network and connectivity configuration

Type:

object({
    ipv6           = optional(bool, true)
    websockets     = optional(bool, true)
    pseudo_ipv4    = optional(string, "off")
    ip_geolocation = optional(bool, true)
    http3          = optional(bool, true)
  })

Default: {}

notification_config

Description: Notification settings for alerts and health checks

Type:

object({
    email_addresses = optional(list(string), [])
    webhook_urls    = optional(list(string), [])
    slack_webhook   = optional(string, "")
  })

Default: {}

page_rules

Description: Custom page rules for caching and performance

Type:

list(object({
    target   = string
    priority = number
    actions  = map(any)
  }))

Default: []

page_rules_enabled

Description: Enable deprecated page rules (requires zone-scoped API token, not account-owned)

Type: bool

Default: false

performance_config

Description: Performance and caching configuration

Type:

object({
    minify = optional(object({
      css  = optional(bool, true)
      html = optional(bool, true)
      js   = optional(bool, true)
    }), {})
    brotli        = optional(bool, true)
    early_hints   = optional(bool, true)
    rocket_loader = optional(bool, false)
    mirage        = optional(bool, true)
    polish        = optional(string, "lossy")
  })

Default: {}

rate_limits

Description: Custom rate limiting rules

Type:

list(object({
    name      = string
    threshold = number
    period    = number
    match = object({
      request = object({
        url_pattern = string
        schemes     = optional(list(string), ["HTTPS"])
        methods     = optional(list(string), ["GET", "POST"])
      })
    })
    action = object({
      mode    = string
      timeout = optional(number, 300)
    })
  }))

Default: []

security_config

Description: Advanced security configuration

Type:

object({
    challenge_ttl       = optional(number, 1800)
    browser_check       = optional(bool, true)
    always_online       = optional(bool, true)
    ip_geolocation      = optional(bool, true)
    email_obfuscation   = optional(bool, true)
    server_side_exclude = optional(bool, true)
  })

Default: {}

services

Description: Map of services to configure DNS records for

Type:

map(object({
    subdomain = string
    target    = string
    type      = string
    ttl       = number
    priority  = optional(number)
    proxied   = optional(bool, true)
  }))

Default: {}

ssl_config

Description: SSL/TLS configuration options

Type:

object({
    mode            = optional(string, "full_strict")
    min_tls_version = optional(string, "1.2")
    tls_1_3         = optional(string, "on")
    always_https    = optional(bool, true)
    hsts_enabled    = optional(bool, true)
    hsts_max_age    = optional(number, 31536000)
  })

Default: {}

tags

Description: Tags to apply to Cloudflare resources

Type: map(string)

Default: {}

trading_config

Description: Trading platform specific configuration

Type:

object({
    api_rate_limit    = optional(number, 1000)
    websocket_enabled = optional(bool, true)
    ssl_mode          = optional(string, "full_strict")
    security_level    = optional(string, "medium")
    bot_management    = optional(bool, true)
  })

Default: {}

waf_rules

Description: Custom WAF rules for the trading platform

Type:

list(object({
    action      = string
    expression  = string
    description = string
    enabled     = optional(bool, true)
  }))

Default: []

worker_config

Description: Worker script configuration. NOTE: Workers are typically deployed via wrangler CLI, not Terraform.

Type:

object({
    api_gateway_enabled = optional(bool, false) # Disabled by default - workers deployed via wrangler
    dns_manager_enabled = optional(bool, false) # Disabled by default - workers deployed via wrangler
    custom_scripts = optional(map(object({
      content = string
      routes  = list(string)
    })), {})
  })

Default: {}

Outputs

The following outputs are exported:

admin_url

Description: Admin panel URL (path-based, NOT subdomain)

api_url

Description: API service URL

app_url

Description: Frontend application URL

cf_access_applications

Description: Cloudflare Access protected applications

cf_access_backend_config

Description: Configuration for backend CF Access validation

cf_access_enabled

Description: Whether Cloudflare Zero Trust Access is enabled

cf_access_entra_idp_id

Description: Cloudflare Access Entra ID identity provider resource ID

cf_access_jwks_url

Description: JWKS URL for backend JWT validation

cf_access_policies

Description: Cloudflare Access policies

cf_access_service_token

Description: Service token for CI/CD automation (sensitive)

cf_access_team_domain

Description: Cloudflare Access team domain for JWKS endpoint

configuration_summary

Description: Summary of all applied configurations

dns_records

Description: Created DNS records with their details

health_checks

Description: Configured health checks (empty map when health_checks.enabled = false)

page_rules

Description: Applied page rules (empty when page_rules_enabled = false)

production_urls

Description: Production environment URLs (only if production)

rate_limits

Description: Applied rate limiting rules

security_config

Description: Applied security configuration

service_urls

Description: URLs for all configured services

waf_rules

Description: Deployed WAF rulesets (custom + managed)

websocket_url

Description: WebSocket service URL

zone_id

Description: Cloudflare Zone ID

zone_name

Description: Zone name (domain)

On this page