Create a Cloudflare Geo WAF Country block with Terraform

610 views Asked by At

I am trying to write a terraform script to apply a country block in Cloudflare for one of my websites. However, I am not entirely sure if I'm doing it right. For context this is using the Free Cloudflare plan.

My terraform script is below:

resource "cloudflare_ruleset" "country_block" {
  zone_id = data.cloudflare_zone.zone.zone_id
  name        = "country block on ${local.web_host}"
  kind        = "zone"
  phase       = "http_request_firewall_custom"

  rules {
    action = "block"
    expression  = "(ip.geoip.country ne \"NZ\")"
    enabled     = true
  }
}

The error I get is

Error: error creating ruleset country block on www.example.com: not entitled to use the firewall custom phase

I can do it manually in the CloudFlare portal, under the WAF Security - Firewall rules, you get 5 for free. So am assuming this is possible in terraform, thought the error potentially indicates a paid plan required

2

There are 2 answers

0
Radu Gabriel On

Hey here is my working example of cloudflare Security - Firewall rules WAF (Web Application Firewall)

Make sure your API token has the required permissions. Take a look at https://developers.cloudflare.com/terraform/tutorial/initialize-terraform/

variable "zone_id" {
  default = "removed_value"
}


resource "cloudflare_filter" "block_ips_from_countries" {
  zone_id     = var.zone_id
  description = "Block IPs from different countries"
  expression  = "(ip.geoip.country in {\"CU\" \"IR\" \"RU\" \"SY\" \"US\" \"KP\"})"
}

resource "cloudflare_firewall_rule" "block_ips_from_countries" {
  zone_id     = var.zone_id
  description = "Block IPs from different countries"
  filter_id   = cloudflare_filter.block_ips_from_countries.id
  action      = "block"
  priority    = 2
}


This example is based on official docs https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/firewall_rule#zone_id

And Note from https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset

If you previously configured Rulesets using the dashboard, you first need to delete them (zone, account documentation) and clean up the resources before attempting to configure them with Terraform. This is because Terraform will fail to apply if configuration already exists to prevent blindly overwriting changes.

I had to delete the rules I manually created in order to let terraform create them

0
rustyMagnet On

There is an alternative. You can use the cloudflare_access_rule for the same thing:

resource "cloudflare_access_rule" "countries_to_challenge" {
  account_id = var.cloudflare_account_id
  for_each   = var.countries_naughty_map
  notes      = "Challenge ${each.key} with country code ${each.value}"
  mode       = "managed_challenge"

  configuration {
    target = "country"
    value  = each.value
  }
}


variable "countries_naughty_map" {
  type = map(any)
  default = {
    "Aussies" = "AU"
    "Kiwis"   = "NZ"
  }
}

Access Rules get evaluated before Firewall Rules. See here. This is also across your zones rather than being on a single zone.