Skip to content

Rate limiting rules

This page provides an example of creating a rate limiting rule in a zone using Terraform.

For more information on rate limiting rules, refer to Rate limiting rules in the Cloudflare WAF documentation.

Before you start

Obtain the necessary account or zone IDs

The Terraform configurations provided in this page need the zone ID (or account ID) of the zone/account where you will deploy rulesets.

  • To retrieve the list of accounts you have access to, including their IDs, use the List accounts operation.
  • To retrieve the list of zones you have access to, including their IDs, use the List zones operation.

Import or delete existing rulesets

Terraform assumes that it has complete control over account and zone rulesets. If you already have rulesets configured in your account or zone, do one of the following:

  • Import existing rulesets to Terraform using the cf-terraforming tool. Recent versions of the tool can generate resource definitions for existing rulesets and import their configuration to Terraform state.
  • Start from scratch by deleting existing rulesets (account and zone rulesets with "kind": "root" and "kind": "zone", respectively) and then defining your rulesets configuration in Terraform.

Create a rate limiting rule

This example creates a rate limiting rule in zone with ID <ZONE_ID> blocking traffic that exceeds the configured rate:

resource "cloudflare_ruleset" "zone_rl" {
zone_id = "<ZONE_ID>"
name = "Rate limiting for my zone"
description = ""
kind = "zone"
phase = "http_ratelimit"
rules {
action = "block"
ratelimit {
characteristics = ["cf.colo.id", "ip.src"]
period = 60
requests_per_period = 100
mitigation_timeout = 600
}
expression = "(http.request.uri.path matches \"^/api/\")"
description = "My rate limiting rule"
enabled = true
}
}

To create another rate limiting rule, add a new rules object to the same cloudflare_ruleset resource.


Account-level example configuration

This example defines a custom ruleset with a single rate limiting rule in account with ID <ACCOUNT_ID> that blocks traffic for the /api/ path exceeding the configured rate. The second cloudflare_ruleset resource defines an execute rule that deploys the custom ruleset for traffic addressed at example.com.

resource "cloudflare_ruleset" "account_rl" {
account_id = <ACCOUNT_ID>
name = "Rate limiting rules for APIs"
description = ""
kind = "custom"
phase = "http_ratelimit"
rules {
action = "block"
ratelimit {
characteristics = ["cf.colo.id", "ip.src"]
period = 60
requests_per_period = 100
mitigation_timeout = 600
}
expression = "http.request.uri.path contains \"/api/\""
description = "API rule"
enabled = true
}
}
# Account-level entry point ruleset for the 'http_ratelimit' phase
resource "cloudflare_ruleset" "account_rl_entrypoint" {
account_id = <ACCOUNT_ID>
name = "Account-level rate limiting"
description = ""
kind = "root"
phase = "http_ratelimit"
depends_on = [cloudflare_ruleset.account_rl]
rules {
# Deploy the previously defined custom ruleset containing a rate limiting rule
action = "execute"
action_parameters {
id = cloudflare_ruleset.account_rl.id
}
expression = "cf.zone.name eq \"example.com\" and cf.zone.plan eq \"ENT\""
description = "Deploy custom ruleset with RL rule"
enabled = true
}
}

Create an advanced rate limiting rule

This example creates a rate limiting rule in zone with ID <ZONE_ID> with:

  • A custom counting expression that includes a response field (http.response.code).
  • A custom JSON response for rate limited requests.
resource "cloudflare_ruleset" "zone_rl_custom_response" {
zone_id = "<ZONE_ID>"
name = "Advanced rate limiting rule for my zone"
description = ""
kind = "zone"
phase = "http_ratelimit"
rules {
action = "block"
action_parameters {
response {
status_code = 429
content = "{\"response\": \"block\"}"
content_type = "application/json"
}
}
ratelimit {
characteristics = ["ip.src", "cf.colo.id"]
period = 10
requests_per_period = 5
mitigation_timeout = 30
counting_expression = "(http.host eq \"www.example.com\") and (http.request.uri.path matches \"^/status/\") and (http.response.code eq 404)"
}
expression = "http.host eq \"www.example.com\" and (http.request.uri.path matches \"^/status/\")"
description = "Rate limit requests to www.example.com when exceeding the threshold of 404 responses on /status/"
enabled = true
}
}

To create another rate limiting rule, add a new rules object to the same cloudflare_ruleset resource.