Cloudflare page rules using terraform-cloudflare provider does not update page rules

1.2k views Asked by At

I am using Terraform + Cloudflare provider.

I created a page rule the fist time I ran terraform plan + terraform apply.

Running the same command a second time returns the error:

Error: Failed to create page rule: error from makeRequest: HTTP status 400: content "{"success":false,"errors":[{"code":1004,"message":"Page Rule validation failed: See messages for details."}],"messages":[{"code":1,"message":".distinctTargetUrl: Your zone already has an existing page rule with that URL. If you are modifying only page rule settings use the Edit Page Rule option instead","type":null}],"result":null}"

TLDR: How can I make Terraform to update an existing page rule only by changing the definition in this file? Isn't it how this was supposed to work?

This is the terraform.tf file:

provider "cloudflare" {
  email = "__EMAIL__"
  api_key = "__GLOBAL_API_KEY__"
}

resource "cloudflare_zone_settings_override" "default_cloudflare_config" {
  zone_id = "__ZONE_ID__"

  settings {
    always_online = "on"
    always_use_https = "off"

    min_tls_version = "1.0"

    opportunistic_encryption = "on"

    tls_1_3 = "zrt"
    automatic_https_rewrites = "on"
    ssl = "strict"

    # 8 days
    browser_cache_ttl = "691200"

  }
}


resource "cloudflare_page_rule" "rule_bypass_wp_admin" {
  target = "*.__DOMAIN__/*wp-admin*"
  zone_id = "__ZONE_ID__"
  priority = 2
  status = "active"

  actions {
    always_use_https = true
    always_online = "off"
    cache_level = "bypass"
    disable_apps = "true"
    disable_performance = true
    disable_security = true
  }
}
3

There are 3 answers

0
fallincode On

Try removing the always_use_https argument so your actions block looks like this:

  actions {
    always_online       = "off"
    cache_level         = "bypass"
    disable_apps        = "true"
    disable_performance = true
    disable_security    = true
  }

Today I discovered that there is some issue with this argument, it looks like a bug.

0
Alex Benfica On

I still can't update via Terraform, so I used Python to delete it before recreating.

        # Delete existing page rules using API before readding with Terraform
        # For some reason, it I could not update then with Terraform without deleting first
        # https://stackoverflow.com/questions/63942345/cloudflare-page-rules-using-terraform-cloudflare-provider-does-not-update-page-r
        page_rules = cf.zones.pagerules.get(zone_id)
        print(page_rules)
        for pr in page_rules:
            cf.zones.pagerules.delete(zone_id, pr.get('id'))
        page_rules = cf.zones.pagerules.get(zone_id)
        if page_rules:
            exit('Failed to delete existing page rules for site')

0
Moses Tapfuma On

Add the following line in your Page rule definition:

lifecycle {
  ignore_changes = [priority]
}

This will instruct Terraform to ignore any changes in this field. That way when you run a terraform apply Terraform picks up the changes as an update to the existing resources as opposed to creating new resources.

In this case, Terraform tries to create a new Page rule which conflicts with Cloudflare limitation that you cannot have multiple page rules acting on the same resource path

TIP: Run terraform plan -out=tfplan this will print out the plan that will be applied on screen and to file. You then get some insight into the changes that Terraform will make and a chance to spot some unintended changes.