cloudflare
Requirements
The following requirements are needed by this module:
-
cloudflare (~> 4.0)
-
random (~> 3.0)
Providers
The following providers are used by this module:
- cloudflare (~> 4.0)
Modules
No modules.
Resources
The following resources are used by this module:
- cloudflare_healthcheck.api_health (resource)
- cloudflare_healthcheck.frontend_health (resource)
- cloudflare_page_rule.api_no_cache (resource)
- cloudflare_page_rule.static_cache (resource)
- cloudflare_page_rule.trading_app_cache (resource)
- cloudflare_page_rule.websocket_no_cache (resource)
- cloudflare_record.autodiscover_m365 (resource)
- cloudflare_record.dkim_m365_selector1 (resource)
- cloudflare_record.dkim_m365_selector2 (resource)
- cloudflare_record.dmarc (resource)
- cloudflare_record.intune_enrollment (resource)
- cloudflare_record.intune_registration (resource)
- cloudflare_record.mx_google_1 (resource)
- cloudflare_record.mx_google_2 (resource)
- cloudflare_record.mx_google_3 (resource)
- cloudflare_record.mx_google_4 (resource)
- cloudflare_record.mx_google_5 (resource)
- cloudflare_record.mx_m365 (resource)
- cloudflare_record.root (resource)
- cloudflare_record.services (resource)
- cloudflare_record.spf (resource)
- cloudflare_record.teams_lyncdiscover (resource)
- cloudflare_record.teams_sip (resource)
- cloudflare_record.www (resource)
- cloudflare_ruleset.managed_waf (resource)
- cloudflare_ruleset.rate_limiting (resource)
- cloudflare_ruleset.trading_waf (resource)
- cloudflare_zero_trust_access_application.admin (resource)
- cloudflare_zero_trust_access_application.api_admin (resource)
- cloudflare_zero_trust_access_application.health (resource)
- cloudflare_zero_trust_access_application.portal (resource)
- cloudflare_zero_trust_access_identity_provider.entra_id (resource)
- cloudflare_zero_trust_access_policy.admin_allow (resource)
- cloudflare_zero_trust_access_policy.api_admin_allow (resource)
- cloudflare_zero_trust_access_policy.api_admin_service_token (resource)
- cloudflare_zero_trust_access_policy.health_allow (resource)
- cloudflare_zero_trust_access_policy.portal_allow (resource)
- cloudflare_zero_trust_access_service_token.ci_automation (resource)
- cloudflare_zone_settings_override.security (resource)
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)