Repository: cloudflare/cf-terraforming

Issue:
CF-TERRAFORMING for CLOUPDFLARE_RULESET resource not terraforming the RULES within ruleset
### Confirmation

- [x] My issue isn't already found on the issue tracker.
- [x] I have replicated my issue using the latest version of the library and it is still present.

### cf-terraforming version

cf-terraforming 0.23.3

### Expected outcome

When using cf-terraforming to terraform the CLOudFLARE_RULESET it should not only bring the basic setting of the ruleset but also the RULES within it, as it did before.

### Actual outcome

The output shows the RULESETS basic config  within the ZONE, but their RULES
```
resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  description = "Created by the Cloudflare security team, this ruleset provides normalization on the URL path"
  kind        = "managed"
  name        = "Cloudflare Normalization Ruleset"
  phase       = "http_request_sanitize"
  zone_id     = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  kind    = "managed"
  name    = "Bot Fight Mode for Likely Bots"
  phase   = "http_request_sbfm"
  zone_id = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  kind    = "managed"
  name    = "Bot Fight Mode for Definite Bots"
  phase   = "http_request_sbfm"
  zone_id = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  description = "Created by the Cloudflare security team, this ruleset is designed to provide fast and effective protection for all your applications. It is frequently updated to cover new vulnerabilities and reduce false positives."
  kind        = "managed"
  name        = "Cloudflare Managed Ruleset"
  phase       = "http_request_firewall_managed"
  zone_id     = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  description = "Cloudflare's implementation of the Open Web Application Security Project (OWASP) ModSecurity Core Rule Set. We routinely monitor for updates from OWASP based on the latest version available from the official code repository"
  kind        = "managed"
  name        = "Cloudflare OWASP Core Ruleset"
  phase       = "http_request_firewall_managed"
  zone_id     = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  description = "Exposed credentials check rules"
  kind        = "managed"
  name        = "Cloudflare Exposed Credentials Check Ruleset"
  phase       = "http_request_firewall_managed"
  zone_id     = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  description = "Automatic mitigation of HTTP-based DDoS attacks. Cloudflare routinely adds signatures to address new attack vectors. Additional configuration allows you to customize the sensitivity of each rule and the performed mitigation action."
  kind        = "managed"
  name        = "DDoS L7 ruleset"
  phase       = "ddos_l7"
  zone_id     = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  description = "Created by the Cloudflare security team, this ruleset is designed to provide protection for free zones"
  kind        = "managed"
  name        = "Cloudflare Managed Free Ruleset"
  phase       = "http_request_firewall_managed"
  zone_id     = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  kind    = "zone"
  name    = "default"
  phase   = "http_request_firewall_managed"
  zone_id = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  description = "Rules maintained by bots team that can run for all plans"
  kind        = "managed"
  name        = "Cloudflare Bot Management rules for all plans"
  phase       = "http_request_sbfm"
  zone_id     = "<redacted>"
}

resource "cloudflare_ruleset" "terraform_managed_resource_<id_redacted>" {
  kind    = "zone"
  name    = "default"
  phase   = "http_request_firewall_custom"
  zone_id = "<redacted>"
}

```

### Steps to reproduce

#Execute the following
```cf-terraforming generate --email myemail@email.com --token <my-CF-token-here> -z <ZONE-ID for which I want the rulesets> --resource-type cloudflare_ruleset > importing-example1.tf```

### References

I'm checking directly on the cf-terraforming repo >> https://github.com/cloudflare/cf-terraforming
And for the supported resources I'm checking the list on your repo: https://github.com/cloudflare/cf-terraforming#:~:text=provider%20%22cloudflare/cloudflare%22-,Supported%20Resources,-v5

Discussion:
@kaincosta: Another important comment:
I checked via CLOUDFLARE API and when doing a curl against: 

```https://api.cloudflare.com/client/v4/zones/<zone-id>/rulesets```

it bring the same information, only the basic settings of the RULESET 
and not the RULES within the rulesets.

 the OLD endpoint`"https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/firewall/rules"` did return that information, but this resource is suppose to be deprecated.

Curl command:
```
❯ curl -X  GET "https://api.cloudflare.com/client/v4/zones/<redacted-zone-id>/rulesets" \
        -H "Authorization: Bearer <redacted-token>" \
        -H "Content-Type: application/json" | jq .
```


OUTPUT:
```
{
  "result": [
    {
      "description": "Created by the Cloudflare security team, this ruleset provides normalization on the URL path",
      "id": "<redacted-zone-id>",
      "kind": "managed",
      "last_updated": "2024-08-01T17:37:11.538019Z",
      "name": "Cloudflare Normalization Ruleset",
      "phase": "http_request_sanitize",
      "version": "6"
    },
    {
      "description": "",
      "id": "<redacted-zone-id>",
      "kind": "managed",
      "last_updated": "2024-12-18T17:13:02.123258Z",
      "name": "Bot Fight Mode for Likely Bots",
      "phase": "http_request_sbfm",
      "source": "firewall_managed",
      "version": "8"
    },
    {
      "description": "",
      "id": "<redacted-zone-id>",
      "kind": "managed",
      "last_updated": "2024-12-18T17:13:03.199618Z",
      "name": "Bot Fight Mode for Definite Bots",
      "phase": "http_request_sbfm",
      "source": "firewall_managed",
      "version": "8"
    },
    {
      "description": "Created by the Cloudflare security team, this ruleset is designed to provide fast and effective protection for all your applications. It is frequently updated to cover new vulnerabilities and reduce false positives.",
      "id": "<redacted-zone-id>",
      "kind": "managed",
      "last_updated": "2025-02-18T17:35:15.131581Z",
      "name": "Cloudflare Managed Ruleset",
      "phase": "http_request_firewall_managed",
      "source": "firewall_managed",
      "version": "232"
    },
    {
      "description": "Cloudflare's implementation of the Open Web Application Security Project (OWASP) ModSecurity Core Rule Set. We routinely monitor for updates from OWASP based on the latest version available from the official code repository",
      "id": "<redacted-zone-id>",
      "kind": "managed",
      "last_updated": "2024-08-19T17:26:58.593021Z",
      "name": "Cloudflare OWASP Core Ruleset",
      "phase": "http_request_firewall_managed",
      "source": "firewall_managed",
      "version": "87"
    },
    {
      "description": "Exposed credentials check rules",
      "id": "<redacted-zone-id>",
      "kind": "managed",
      "last_updated": "2024-08-01T17:37:12.291474Z",
      "name": "Cloudflare Exposed Credentials Check Ruleset",
      "phase": "http_request_firewall_managed",
      "source": "firewall_managed",
      "version": "89"
    },
    {
      "description": "Automatic mitigation of HTTP-based DDoS attacks. Cloudflare routinely adds signatures to address new attack vectors. Additional configuration allows you to customize the sensitivity of each rule and the performed mitigation action.",
      "id": "<redacted-zone-id>",
      "kind": "managed",
      "last_updated": "2025-02-19T21:08:00.815518Z",
      "name": "DDoS L7 ruleset",
      "phase": "ddos_l7",
      "version": "2718"
    },
    {
      "description": "Created by the Cloudflare security team, this ruleset is designed to provide protection for free zones",
      "id": "<redacted-zone-id>",
      "kind": "managed",
      "last_updated": "2024-08-01T17:37:10.825759Z",
      "name": "Cloudflare Managed Free Ruleset",
      "phase": "http_request_firewall_managed",
      "source": "firewall_managed",
      "version": "57"
    },
    {
      "description": "",
      "id": "<redacted-zone-id>",
      "kind": "zone",
      "last_updated": "2023-09-06T21:04:30.352935Z",
      "name": "default",
      "phase": "http_request_firewall_managed",
      "source": "firewall_managed",
      "version": "2"
    },
    {
      "description": "Rules maintained by bots team that can run for all plans",
      "id": "<redacted-zone-id>",
      "kind": "managed",
      "last_updated": "2025-02-12T23:39:38.344875Z",
      "name": "Cloudflare Bot Management rules for all plans",
      "phase": "http_request_sbfm",
      "source": "firewall_managed",
      "version": "10"
    },
    {
      "description": "",
      "id": "<redacted-zone-id>",
      "kind": "zone",
      "last_updated": "2025-02-20T11:04:18.084537Z",
      "name": "default",
      "phase": "http_request_firewall_custom",
      "source": "firewall_custom",
      "version": "50"
    }
  ],
  "success": true,
  "errors": [],
  "messages": []
}


```@kaincosta: Another question, would this have any impact on how terraform is able to track the rules within a ruleset?@kaincosta: I just tried with a new endpoint from the API: `curl -X GET https://api.cloudflare.com/client/v4/zones/<zone-id>/rulesets/<ruleset-id>`, which returned the expected output, I'm wondering inthe CF-TERRAFORMING, what resource would bring the same output as this?@cheewai-bash: Using cf-terraform v0.23.3 with the latest cloudflare/cloudflare provisioner v.5.1.0, I encounter exactly the same issue. `cf-terraforming generate --resource-type cloudflare_ruleset` output is missing `rules` attribute.@cheewai-bash: > Using cf-terraform v0.23.3 with the latest cloudflare/cloudflare provisioner v.5.1.0, I encounter exactly the same issue. `cf-terraforming generate --resource-type cloudflare_ruleset` output is missing `rules` attribute.

`--account` and `--zone` arguments are mutually-exclusive.

When run with `--zone` argument

```text
DEBU[0000] initializing cloudflare-go with API Token     account_Id= zone_id=XXX-REDACTED-XXX
DEBU[0001] initializing Terraform in .                  
DEBU[0003] detected provider                             version=5.1.0
DEBU[0003] reading Terraform schema for Cloudflare provider 
DEBU[0004] reading and building resource                 resource=cloudflare_ruleset
DEBU[0005] generating resource output                    count=20 resource=cloudflare_ruleset
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key account_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
resource "cloudflare_ruleset" "terraform_managed_resource_70339d97bdb34195bbf054b1ebe81f76" {
  description = "Created by the Cloudflare security team, this ruleset provides normalization on the URL path"
  kind        = "managed"
  name        = "Cloudflare Normalization Ruleset"
  phase       = "http_request_sanitize"
  zone_id     = "XXX-REDACTED-XXX"
}
```

When run with `--account` argument

```text
DEBU[0001] initializing Terraform in .                  
DEBU[0002] detected provider                             version=5.1.0
DEBU[0002] reading Terraform schema for Cloudflare provider 
DEBU[0004] reading and building resource                 resource=cloudflare_ruleset
DEBU[0005] generating resource output                    count=3 resource=cloudflare_ruleset
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key zone_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key zone_id, value <nil>, value type <nil> 
DEBU[0005] attribute "rules" has not been generated     
DEBU[0005] got unknown attribute configuration: key zone_id, value <nil>, value type <nil> 
resource "cloudflare_ruleset" "terraform_managed_resource_4d21379b4f9f4bb088e0729962c8b3cf" {
  account_id  = "XXX-REDACTED-XXX"
  description = "Automatic mitigation of HTTP-based DDoS attacks. Cloudflare routinely adds signatures to address new attack vectors. Additional configuration allows you to customize the sensitivity of each rule and the performed mitigation action."
  kind        = "managed"
  name        = "DDoS L7 ruleset"
  phase       = "ddos_l7"
}
```@stboissdev: +1@nhanvqit: +1 same issue@vhgbao01: same problem +1@aimuz: I encountered the same problem, and it seems to have lasted for a month@aimuz: I'm glad I've made progress on this issue. I solved this problem in the following ways.

The main reason for this problem is that the list method does not list the details, while the get method does. Therefore, this problem can be solved by importing the status. 


```bash
cf-terraforming generate --email myemail@email.com --token <my-CF-token-here> -z <ZONE-ID for which I want the rulesets> --resource-type cloudflare_ruleset > importing-example1.tf

cf-terraforming import --email myemail@email.com --token <my-CF-token-here> -z <ZONE-ID for which I want the rulesets> --resource-type cloudflare_ruleset > 1.sh

bash 1.sh

terraform show > importing-example1.tf
```@gui-wf: @aimuz That worked and helped me get on the right track! Thank you!

So, if am understanding correctly, what you did:
1. generate *ruleset* resources -> Gets us each ruleset basic metadata, but not all the rules in it. Before doing this,
2. generate the Terraform imports for all *rulesets* -> Makes Terraform create state of those *rulesets*. This state is created based on whats in the Infrastructure, Cloudflare side.
3. After having the necessary Terraform metadata, having the state in sync with the Infrastructure, we can finally generate the HCL that respects the state.

Am I thinking right?

### Some Testing I did
Following your steps:
1. the `cf-terraforming generate`, 
2. followed by `cf-terraforming import ... > tf-import-commands.sh`,
3. followed by `bash tf-import-commands.sh`, 
4. and finally `terraform show > generated.tf`. 
- If I then try to Terraform Plan, it errors saying that I can't define the *id* attributes as they are read-only. To appease my mind a bit, I would like to know if you hit this same error @aimuz?
  > **NOTE:** I fixed this error by deleting all definitions of *id*'s. 
  > **Another NOTE** I want to make for anyone like me who has beginner/-ish knowledge of Terraform: (Please correct me if I am wrong. This is what I am gathering from my tests) 
  >    - The state will have the ids since that is what represents the real deployed infrastructure, which in our case is the Cloudflare side. The resource definitions themselves should not have the *ids* since this is something that Cloudflare generates, not our Terraform instances.

Based on your method, I then continued on what I was doing, which is trying to create a full representation of the Cloudflare configurations but in HCL/Terrafrom.

If I  create the (modern) import blocks with `cf-terraforming import --modern-import-block ...`, and then try doing `terraform plan`, Terraform invites me to use `-generate-config-out=generated.tf` like so:

```bash
terraform plan -generate-config-out=generated.tf
```

That gives me a 100% valid HCL configuration - `terraform plan`-ning does not error.

### Idk what this issue is/where it comes from...

However, something weird happens. Comparing the values the Cloudflare REST API gets me and what this process gave me:
 
- I have ruleset rules that have the **attribute *categories*** and others that do not. For the ones that don't have this attribute *categories*, on `terraform plan`, Terraform wants to do **in-place changes of** these resources, telling me that it will add this **non-existent *categories* attribute** with (known after apply).

    ![Image](https://github.com/user-attachments/assets/5980ba4f-8ea6-457d-8318-f1e3a9cbab59)
    
    ... when my Terraform HCL does not have this attribute set, not even set as `= null`.@jhutchings1: Thanks all, this is one we're aware of. The LIST endpoint on the rulesets API doesn't return the details of the ruleset itself. As a result, cf_terraforming exports only the metadata which was in that API call. @musa-cf do we have a plan to remedy this one? @madorb: Any idea when the next release is planned for? this issue is sort of a major showstopper for v5 usage...@jhutchings1: @musa-cf has been working on the cf-terraforming updates, and we're in validation right now. We should be ready to go in the next week or so assuming we don't find any unexpected issues. @madorb: thanks! 🤞 

I attempted to build the latest from `master` locally to unblock myself, but that appears to not work either - even worse, there's zero output! 

```
❯ ../../exploratory/cf-terraforming/cf-terraforming generate --resource-type cloudflare_ruleset --zone <myzone>
❯ 
```@elliotdobson: > I attempted to build the latest from master locally to unblock myself, but that appears to not work either - even worse, there's zero output!

+1 same here (using 40e0f0b).

Running with `--verbose` flag shows the successful HTTP requests to the Cloudflare API but `cf-terraforming` is not outputting any Terraform resources.@jhutchings1: > I attempted to build the latest from `master` locally to unblock myself, but that appears to not work either - even worse, there's zero output!

@musa-cf @vaishakdinesh can you have a look? 



@vaishakdinesh: > > I attempted to build the latest from `master` locally to unblock myself, but that appears to not work either - even worse, there's zero output!
> 
> [@musa-cf](https://github.com/musa-cf) [@vaishakdinesh](https://github.com/vaishakdinesh) can you have a look?

Taking a look! 

Solution patch:
diff --git a/.golintci.yml b/.golintci.yml
index 6bf3bcd..6c056c9 100644
--- a/.golintci.yml
+++ b/.golintci.yml
@@ -1,27 +1,39 @@
+version: "2"
 run:
-  timeout: 5m
+  modules-download-mode: readonly
   issues-exit-code: 1
   tests: true
-  skip-dirs-use-default: true
-  modules-download-mode: readonly
-  skip-files:
-    - internal/app/cf-terraforming/cmd/resource_to_endpoint_mapping.go
-
 linters:
-  disable-all: true
+  default: none
+  enable:
+    - bodyclose
+    - contextcheck
+    - errcheck
+    - errname
+    - errorlint
+    - godot
+    - misspell
+    - nilerr
+    - tparallel
+    - unparam
+    - whitespace
+  exclusions:
+    generated: lax
+    presets:
+      - comments
+      - common-false-positives
+      - legacy
+      - std-error-handling
+    paths:
+      - third_party$
+      - builtin$
+      - examples$
+formatters:
   enable:
-    - bodyclose    # ensure HTTP response bodies are successfully closed.
-    - contextcheck # check we are passing context an inherited context.
-    - gofmt        # checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification.
-    - errname      # checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`.
-    - errcheck     # a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases.
-    - errorlint    # used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
-    - godot        # check if comments end in a period.
-    - misspell     # finds commonly misspelled English words in comments.
-    - nilerr       # checks that there is no simultaneous return of nil error and an invalid value.
-    - tparallel    # detects inappropriate usage of t.Parallel() method in your Go test codes.
-    - unparam      # reports unused function parameters.
-    - whitespace   # detection of leading and trailing whitespace.
-
-output:
-  format: colored-line-number
+    - gofmt
+  exclusions:
+    generated: lax
+    paths:
+      - third_party$
+      - builtin$
+      - examples$
diff --git a/README.md b/README.md
index d05b659..53032a4 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,6 @@ Flags:
       --hostname string                     Hostname to use to query the API
   -k, --key string                          API Key generated on the 'My Profile' page. See: https://dash.cloudflare.com/profile
       --modern-import-block                 Whether to generate HCL import blocks for generated resources instead of terraform import compatible CLI commands. This is only compatible with Terraform 1.5+
-      --provider-registry-hostname string   Hostname to use for provider registry lookups (default "registry.terraform.io")
       --resource-type string                Comma delimitered string of which resource(s) you wish to generate
       --terraform-binary-path string        Path to an existing Terraform binary (otherwise, one will be downloaded)
       --terraform-install-path string       Path to an initialized Terraform working directory (default ".")
@@ -182,14 +181,6 @@ cf-terraforming import \
   --zone $CLOUDFLARE_ZONE_ID
 ```
 
-## Using non-standard registries
-
-By default, we use the Hashicorp registry (registry.terraform.io) for looking up
-the provider to introspect the schema. If you are attempting to use another
-registry, you will need to provide the `--provider-registry-hostname` flag or
-`CLOUDFLARE_PROVIDER_REGISTRY_HOSTNAME` environment variable to query the correct
-registry.
-
 ## Using non-standard Terraform binaries
 
 Internally, we use [`terraform-exec`](https://github.com/hashicorp/terraform-exec)
@@ -206,7 +197,7 @@ existing binary, or you wish to provide a Terraform compatible binary (such as
 ## CDKTF
 
 If you'd like to use [cdktf](https://developer.hashicorp.com/terraform/cdktf)
-for your project resources, you can pipe the output from `cf-terraforming` into 
+for your project resources, you can pipe the output from `cf-terraforming` into
 `cdktf convert` in order to correctly generate CDKTF output automatically.
 
 Example:
diff --git a/go.mod b/go.mod
index 8b74f59..b84d0f9 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@ require (
 	github.com/mitchellh/go-homedir v1.1.0
 	github.com/sirupsen/logrus v1.9.3
 	github.com/spf13/cobra v1.9.1
-	github.com/spf13/viper v1.20.0
+	github.com/spf13/viper v1.20.1
 	github.com/stretchr/testify v1.10.0
 	github.com/tidwall/gjson v1.18.0
 	github.com/zclconf/go-cty v1.16.2
diff --git a/go.sum b/go.sum
index c1ca995..7a9579d 100644
--- a/go.sum
+++ b/go.sum
@@ -115,8 +115,8 @@ github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
 github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.20.0 h1:zrxIyR3RQIOsarIrgL8+sAvALXul9jeEPa06Y0Ph6vY=
-github.com/spf13/viper v1.20.0/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
+github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
+github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
diff --git a/internal/app/cf-terraforming/cmd/generate.go b/internal/app/cf-terraforming/cmd/generate.go
index be283cf..9e7da95 100644
--- a/internal/app/cf-terraforming/cmd/generate.go
+++ b/internal/app/cf-terraforming/cmd/generate.go
@@ -14,7 +14,6 @@ import (
 
 	cfv0 "github.com/cloudflare/cloudflare-go"
 	"github.com/cloudflare/cloudflare-go/v4"
-	"github.com/cloudflare/cloudflare-go/v4/option"
 	"github.com/hashicorp/go-version"
 	"github.com/hashicorp/hc-install/product"
 	"github.com/hashicorp/hc-install/releases"
@@ -54,7 +53,6 @@ func generateResources() func(cmd *cobra.Command, args []string) {
 		accountID = viper.GetString("account")
 		workingDir := viper.GetString("terraform-install-path")
 		execPath := viper.GetString("terraform-binary-path")
-		providerRegistryHostname := viper.GetString("provider-registry-hostname")
 
 		// Download terraform if no existing binary was provided
 		if execPath == "" {
@@ -82,7 +80,9 @@ func generateResources() func(cmd *cobra.Command, args []string) {
 
 		// Setup and configure Terraform to operate in the temporary directory where
 		// the provider is already configured.
-		log.Debugf("initializing Terraform in %s", workingDir)
+		log.WithFields(logrus.Fields{
+			"directory": workingDir,
+		}).Debug("initializing Terraform")
 		tf, err := tfexec.NewTerraform(workingDir, execPath)
 		if err != nil {
 			log.Fatal(err)
@@ -93,18 +93,34 @@ func generateResources() func(cmd *cobra.Command, args []string) {
 			log.Fatalf("failed to retrieve terraform and provider version information: %s", err)
 		}
 
-		providerVersionString := providerVersion[providerRegistryHostname+"/cloudflare/cloudflare"].String()
+		var registryPath string
+		for provider := range providerVersion {
+			if strings.Contains(provider, "/cloudflare/cloudflare") {
+				registryPath = provider
+				continue
+			}
+		}
+
+		detectedVersion, ok := providerVersion[registryPath]
+		if !ok {
+			log.WithFields(logrus.Fields{
+				"available_registries": providerVersion,
+			}).Fatal("failed to find registry")
+		}
+
+		providerVersionString := detectedVersion.String()
 		log.WithFields(logrus.Fields{
-			"version": providerVersionString,
+			"version":  providerVersionString,
+			"registry": registryPath,
 		}).Debug("detected provider")
 
-		log.Debug("reading Terraform schema for Cloudflare provider")
+		log.Debug("reading Terraform schema")
 		ps, err := tf.ProvidersSchema(context.Background())
 		if err != nil {
 			log.Fatal("failed to read provider schema", err)
 		}
 
-		s := ps.Schemas[providerRegistryHostname+"/cloudflare/cloudflare"]
+		s := ps.Schemas[registryPath]
 		if s == nil {
 			log.Fatal("failed to detect provider installation")
 		}
@@ -127,7 +143,12 @@ func generateResources() func(cmd *cobra.Command, args []string) {
 			resourceCount := 0
 			var jsonStructData []interface{}
 
-			if strings.HasPrefix(providerVersionString, "5") {
+			// The ruleset API has many gotchas that are accounted for in how we build
+			// the 'response' object that feeds into the HCL generation, and it's difficult
+			// to ensure the same compatability using the generated SDK.
+			useOldSDK := resourceType == "cloudflare_ruleset"
+
+			if strings.HasPrefix(providerVersionString, "5") && !useOldSDK {
 				if resourceToEndpoint[resourceType]["list"] == "" && resourceToEndpoint[resourceType]["get"] == "" {
 					log.WithFields(logrus.Fields{
 						"resource": resourceType,
@@ -159,12 +180,6 @@ func generateResources() func(cmd *cobra.Command, args []string) {
 				placeholderReplacer := strings.NewReplacer("{account_id}", accountID, "{zone_id}", zoneID)
 				endpoint = placeholderReplacer.Replace(endpoint)
 
-				if apiToken != "" {
-					api.Options = append(api.Options, option.WithAPIToken(apiToken))
-				} else {
-					api.Options = append(api.Options, option.WithAPIKey(apiKey), option.WithAPIEmail(apiEmail))
-				}
-
 				pathParams, ok := resourceIDsMap[resourceType]
 				if ok && len(pathParams) > 0 {
 					endpoints := make([]string, 0)
@@ -948,6 +963,18 @@ func generateResources() func(cmd *cobra.Command, args []string) {
 						log.Fatal(err)
 					}
 
+					if strings.HasPrefix(providerVersionString, "5") {
+						for i := 0; i < resourceCount; i++ {
+							rules := jsonStructData[i].(map[string]interface{})["rules"]
+							if rules != nil {
+								for ruleCounter := range rules.([]interface{}) {
+									rules.([]interface{})[ruleCounter].(map[string]interface{})["id"] = nil
+								}
+							}
+						}
+						continue
+					}
+
 					// Make the rules have the correct header structure
 					for i, ruleset := range jsonStructData {
 						if ruleset.(map[string]interface{})["rules"] != nil {
@@ -1795,7 +1822,11 @@ func GetAPIResponse(result *http.Response, pathParams []string, endpoints ...str
 			log.Fatalf("failed to unmarshal result: %s", err)
 		}
 
-		processCustomCasesV5(&jsonStructData, resourceType, pathParams[i])
+		param := ""
+		if len(pathParams) > 0 {
+			param = pathParams[i]
+		}
+		processCustomCasesV5(&jsonStructData, resourceType, param)
 		results = append(results, jsonStructData...)
 	}
 	return results, nil
diff --git a/internal/app/cf-terraforming/cmd/import.go b/internal/app/cf-terraforming/cmd/import.go
index 7fcb2cc..58930b7 100644
--- a/internal/app/cf-terraforming/cmd/import.go
+++ b/internal/app/cf-terraforming/cmd/import.go
@@ -115,7 +115,9 @@ func runImport() func(cmd *cobra.Command, args []string) {
 
 		// Setup and configure Terraform to operate in the temporary directory where
 		// the provider is already configured.
-		log.Debugf("initializing Terraform in %s", workingDir)
+		log.WithFields(logrus.Fields{
+			"directory": workingDir,
+		}).Debug("initializing Terraform")
 		tf, err := tfexec.NewTerraform(workingDir, execPath)
 		if err != nil {
 			log.Fatal(err)
@@ -126,9 +128,25 @@ func runImport() func(cmd *cobra.Command, args []string) {
 			log.Fatalf("failed to retrieve terraform and provider version information: %s", err)
 		}
 
-		providerVersionString = providerVersion[providerRegistryHostname+"/cloudflare/cloudflare"].String()
+		var registryPath string
+		for provider := range providerVersion {
+			if strings.Contains(provider, "/cloudflare/cloudflare") {
+				registryPath = provider
+				continue
+			}
+		}
+
+		detectedVersion, ok := providerVersion[registryPath]
+		if !ok {
+			log.WithFields(logrus.Fields{
+				"available_registries": providerVersion,
+			}).Fatal("failed to find registry")
+		}
+
+		providerVersionString := detectedVersion.String()
 		log.WithFields(logrus.Fields{
-			"version": providerVersionString,
+			"version":  providerVersionString,
+			"registry": registryPath,
 		}).Debug("detected provider")
 
 		var jsonStructData []interface{}
diff --git a/internal/app/cf-terraforming/cmd/root.go b/internal/app/cf-terraforming/cmd/root.go
index 463006c..62332ef 100644
--- a/internal/app/cf-terraforming/cmd/root.go
+++ b/internal/app/cf-terraforming/cmd/root.go
@@ -1,13 +1,14 @@
 package cmd
 
 import (
+	"strings"
+
 	cfv0 "github.com/cloudflare/cloudflare-go"
 	"github.com/cloudflare/cloudflare-go/v4"
 	homedir "github.com/mitchellh/go-homedir"
 	"github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
-	"strings"
 )
 
 var (
@@ -124,7 +125,7 @@ func init() {
 		log.Fatal(err)
 	}
 
-	rootCmd.PersistentFlags().StringVarP(&providerRegistryHostname, "provider-registry-hostname", "", "registry.terraform.io", "Hostname to use for provider registry lookups")
+	rootCmd.PersistentFlags().StringVarP(&providerRegistryHostname, "provider-registry-hostname", "", "", "Hostname to use for provider registry lookups. Deprecated: this is no longer needed to be configured for custom registries.")
 	if err = viper.BindPFlag("provider-registry-hostname", rootCmd.PersistentFlags().Lookup("provider-registry-hostname")); err != nil {
 		log.Fatal(err)
 	}
diff --git a/internal/app/cf-terraforming/cmd/util.go b/internal/app/cf-terraforming/cmd/util.go
index 1108450..41e8cef 100644
--- a/internal/app/cf-terraforming/cmd/util.go
+++ b/internal/app/cf-terraforming/cmd/util.go
@@ -10,7 +10,9 @@ import (
 	"sort"
 	"strings"
 
-	cloudflare "github.com/cloudflare/cloudflare-go"
+	cfv0 "github.com/cloudflare/cloudflare-go"
+	"github.com/cloudflare/cloudflare-go/v4"
+	"github.com/cloudflare/cloudflare-go/v4/option"
 	"github.com/hashicorp/hcl/v2/hclwrite"
 	tfjson "github.com/hashicorp/terraform-json"
 	"github.com/sirupsen/logrus"
@@ -98,14 +100,14 @@ func sharedPreRun(cmd *cobra.Command, args []string) {
 		}).Debug("initializing cloudflare-go with API Token")
 	}
 
-	var options []cloudflare.Option
+	var options []cfv0.Option
 
 	if hostname != "" {
-		options = append(options, cloudflare.BaseURL("https://"+hostname+"/client/v4"))
+		options = append(options, cfv0.BaseURL("https://"+hostname+"/client/v4"))
 	}
 
 	if verbose {
-		options = append(options, cloudflare.Debug(true))
+		options = append(options, cfv0.Debug(true))
 	}
 
 	var err error
@@ -116,9 +118,11 @@ func sharedPreRun(cmd *cobra.Command, args []string) {
 		var useToken = apiToken != ""
 
 		if useToken {
-			apiV0, err = cloudflare.NewWithAPIToken(apiToken, options...)
+			apiV0, err = cfv0.NewWithAPIToken(apiToken, options...)
+			api = cloudflare.NewClient(option.WithAPIToken(apiToken))
 		} else {
-			apiV0, err = cloudflare.New(apiKey, apiEmail, options...)
+			apiV0, err = cfv0.New(apiKey, apiEmail, options...)
+			api = cloudflare.NewClient(option.WithAPIKey(apiKey), option.WithAPIEmail(apiEmail))
 		}
 
 		if err != nil {



Test patch:
diff --git a/internal/app/cf-terraforming/cmd/generate_test.go b/internal/app/cf-terraforming/cmd/generate_test.go
index 25d3ac3..02bfb13 100644
--- a/internal/app/cf-terraforming/cmd/generate_test.go
+++ b/internal/app/cf-terraforming/cmd/generate_test.go
@@ -298,9 +298,9 @@ func TestResourceGenerationV5(t *testing.T) {
 		// "cloudflare list (hostname)":                         {identiferType: "account", resourceType: "cloudflare_list", testdataFilename: "cloudflare_list_hostname"},
 		// "cloudflare list (ip)":                               {identiferType: "account", resourceType: "cloudflare_list", testdataFilename: "cloudflare_list_ip"},
 		// "cloudflare list (redirect)":                         {identiferType: "account", resourceType: "cloudflare_list", testdataFilename: "cloudflare_list_redirect"},
-		// "cloudflare load balancer monitor":                   {identiferType: "account", resourceType: "cloudflare_load_balancer_monitor", testdataFilename: "cloudflare_load_balancer_monitor"},
-		// "cloudflare load balancer pool":                      {identiferType: "account", resourceType: "cloudflare_load_balancer_pool", testdataFilename: "cloudflare_load_balancer_pool"},
-		// "cloudflare load balancer":                           {identiferType: "zone", resourceType: "cloudflare_load_balancer", testdataFilename: "cloudflare_load_balancer"},
+		"cloudflare load balancer":         {identiferType: "zone", resourceType: "cloudflare_load_balancer", testdataFilename: "cloudflare_load_balancer"},
+		"cloudflare load balancer monitor": {identiferType: "account", resourceType: "cloudflare_load_balancer_monitor", testdataFilename: "cloudflare_load_balancer_monitor"},
+		"cloudflare load balancer pool":    {identiferType: "account", resourceType: "cloudflare_load_balancer_pool", testdataFilename: "cloudflare_load_balancer_pool"},
 		// "cloudflare logpush jobs with filter":                {identiferType: "zone", resourceType: "cloudflare_logpush_job", testdataFilename: "cloudflare_logpush_job_with_filter"},
 		// "cloudflare logpush jobs":                            {identiferType: "zone", resourceType: "cloudflare_logpush_job", testdataFilename: "cloudflare_logpush_job"},
 		"cloudflare managed transforms":    {identiferType: "zone", resourceType: "cloudflare_managed_transforms", testdataFilename: "cloudflare_managed_transforms"},
@@ -314,44 +314,44 @@ func TestResourceGenerationV5(t *testing.T) {
 		"cloudflare dns record simple": {identiferType: "zone", resourceType: "cloudflare_dns_record", testdataFilename: "cloudflare_dns_record"},
 		// "cloudflare dns record subdomain":                    {identiferType: "zone", resourceType: "cloudflare_dns_record", testdataFilename: "cloudflare_dns_record_subdomain"},
 		// "cloudflare dns record TXT SPF":                      {identiferType: "zone", resourceType: "cloudflare_dns_record", testdataFilename: "cloudflare_dns_record_txt_spf"},
-		"cloudflare dns zone transfers acl":       {identiferType: "account", resourceType: "cloudflare_dns_zone_transfers_acl", testdataFilename: "cloudflare_dns_zone_transfers_acl"},
-		"cloudflare dns zone transfers incoming":  {identiferType: "zone", resourceType: "cloudflare_dns_zone_transfers_incoming", testdataFilename: "cloudflare_dns_zone_transfers_incoming"},
-		"cloudflare dns zone transfers outgoing":  {identiferType: "zone", resourceType: "cloudflare_dns_zone_transfers_outgoing", testdataFilename: "cloudflare_dns_zone_transfers_outgoing"},
-		"cloudflare dns zone transfers peer":      {identiferType: "account", resourceType: "cloudflare_dns_zone_transfers_peer", testdataFilename: "cloudflare_dns_zone_transfers_peer"},
-		"cloudflare dns zone transfers tsig":      {identiferType: "account", resourceType: "cloudflare_dns_zone_transfers_tsig", testdataFilename: "cloudflare_dns_zone_transfers_tsig"},
-		"cloudflare leaked credential check":      {identiferType: "zone", resourceType: "cloudflare_leaked_credential_check", testdataFilename: "cloudflare_leaked_credential_check"},
-		"cloudflare leaked credential check rule": {identiferType: "zone", resourceType: "cloudflare_leaked_credential_check_rule", testdataFilename: "cloudflare_leaked_credential_check_rule"},
-		"cloudflare list":                         {identiferType: "account", resourceType: "cloudflare_list", testdataFilename: "cloudflare_list"},
-		"cloudflare logpush job":                  {identiferType: "account", resourceType: "cloudflare_logpush_job", testdataFilename: "cloudflare_logpush_job"},
-		"cloudflare logpull retention":            {identiferType: "zone", resourceType: "cloudflare_logpull_retention", testdataFilename: "cloudflare_logpull_retention"},
-		"cloudflare notification policy":          {identiferType: "account", resourceType: "cloudflare_notification_policy", testdataFilename: "cloudflare_notification_policy"},
-		"cloudflare notification policy webhooks": {identiferType: "account", resourceType: "cloudflare_notification_policy_webhooks", testdataFilename: "cloudflare_notification_policy_webhooks"},
-		"cloudflare pages project":                {identiferType: "account", resourceType: "cloudflare_pages_project", testdataFilename: "cloudflare_pages_project"},
-		"cloudflare page shield policy":           {identiferType: "zone", resourceType: "cloudflare_page_shield_policy", testdataFilename: "cloudflare_page_shield_policy"},
-		"cloudflare r2 bucket":                    {identiferType: "account", resourceType: "cloudflare_r2_bucket", testdataFilename: "cloudflare_r2_bucket"},
-		"cloudflare page rule":                    {identiferType: "zone", resourceType: "cloudflare_page_rule", testdataFilename: "cloudflare_page_rule"},
-		// "cloudflare ruleset (ddos_l7)":                       {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_ddos_l7"},
-		// "cloudflare ruleset (http_log_custom_fields)":        {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_log_custom_fields"},
-		// "cloudflare ruleset (http_ratelimit)":                {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_ratelimit"},
-		// "cloudflare ruleset (http_request_cache_settings)":   {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_http_request_cache_settings"},
-		// "cloudflare ruleset (http_request_firewall_custom)":  {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_request_firewall_custom"},
-		// "cloudflare ruleset (http_request_firewall_managed)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_request_firewall_managed"},
-		// "cloudflare ruleset (http_request_late_transform)":   {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_request_late_transform"},
-		// "cloudflare ruleset (http_request_sanitize)":         {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_request_sanitize"},
-		// "cloudflare ruleset (no configuration)":              {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_no_configuration"},
-		// "cloudflare ruleset (override remapping = disabled)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_override_remapping_disabled"},
-		// "cloudflare ruleset (override remapping = enabled)":  {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_override_remapping_enabled"},
-		// "cloudflare ruleset (rewrite to empty query string)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_rewrite_to_empty_query_parameter"},
-		// "cloudflare ruleset":                                 {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone"},
-		"cloudflare stream":                {identiferType: "account", resourceType: "cloudflare_stream", testdataFilename: "cloudflare_stream"},
-		"cloudflare stream keys":           {identiferType: "account", resourceType: "cloudflare_stream_key", testdataFilename: "cloudflare_stream_key"},
-		"cloudflare stream live input":     {identiferType: "account", resourceType: "cloudflare_stream_live_input", testdataFilename: "cloudflare_stream_live_input"},
-		"cloudflare stream webhook":        {identiferType: "account", resourceType: "cloudflare_stream_webhook", testdataFilename: "cloudflare_stream_webhook"},
-		"cloudflare snippets":              {identiferType: "zone", resourceType: "cloudflare_snippets", testdataFilename: "cloudflare_snippets"},
-		"cloudflare snippet rules":         {identiferType: "zone", resourceType: "cloudflare_snippet_rules", testdataFilename: "cloudflare_snippet_rules"},
-		"cloudflare tiered cache":          {identiferType: "zone", resourceType: "cloudflare_tiered_cache", testdataFilename: "cloudflare_tiered_cache"},
-		"cloudflare regional hostnames":    {identiferType: "zone", resourceType: "cloudflare_regional_hostname", testdataFilename: "cloudflare_regional_hostname"},
-		"cloudflare regional tiered cache": {identiferType: "zone", resourceType: "cloudflare_regional_tiered_cache", testdataFilename: "cloudflare_regional_tiered_cache"},
+		"cloudflare dns zone transfers acl":                  {identiferType: "account", resourceType: "cloudflare_dns_zone_transfers_acl", testdataFilename: "cloudflare_dns_zone_transfers_acl"},
+		"cloudflare dns zone transfers incoming":             {identiferType: "zone", resourceType: "cloudflare_dns_zone_transfers_incoming", testdataFilename: "cloudflare_dns_zone_transfers_incoming"},
+		"cloudflare dns zone transfers outgoing":             {identiferType: "zone", resourceType: "cloudflare_dns_zone_transfers_outgoing", testdataFilename: "cloudflare_dns_zone_transfers_outgoing"},
+		"cloudflare dns zone transfers peer":                 {identiferType: "account", resourceType: "cloudflare_dns_zone_transfers_peer", testdataFilename: "cloudflare_dns_zone_transfers_peer"},
+		"cloudflare dns zone transfers tsig":                 {identiferType: "account", resourceType: "cloudflare_dns_zone_transfers_tsig", testdataFilename: "cloudflare_dns_zone_transfers_tsig"},
+		"cloudflare leaked credential check":                 {identiferType: "zone", resourceType: "cloudflare_leaked_credential_check", testdataFilename: "cloudflare_leaked_credential_check"},
+		"cloudflare leaked credential check rule":            {identiferType: "zone", resourceType: "cloudflare_leaked_credential_check_rule", testdataFilename: "cloudflare_leaked_credential_check_rule"},
+		"cloudflare list":                                    {identiferType: "account", resourceType: "cloudflare_list", testdataFilename: "cloudflare_list"},
+		"cloudflare logpush job":                             {identiferType: "account", resourceType: "cloudflare_logpush_job", testdataFilename: "cloudflare_logpush_job"},
+		"cloudflare logpull retention":                       {identiferType: "zone", resourceType: "cloudflare_logpull_retention", testdataFilename: "cloudflare_logpull_retention"},
+		"cloudflare notification policy":                     {identiferType: "account", resourceType: "cloudflare_notification_policy", testdataFilename: "cloudflare_notification_policy"},
+		"cloudflare notification policy webhooks":            {identiferType: "account", resourceType: "cloudflare_notification_policy_webhooks", testdataFilename: "cloudflare_notification_policy_webhooks"},
+		"cloudflare pages project":                           {identiferType: "account", resourceType: "cloudflare_pages_project", testdataFilename: "cloudflare_pages_project"},
+		"cloudflare page shield policy":                      {identiferType: "zone", resourceType: "cloudflare_page_shield_policy", testdataFilename: "cloudflare_page_shield_policy"},
+		"cloudflare r2 bucket":                               {identiferType: "account", resourceType: "cloudflare_r2_bucket", testdataFilename: "cloudflare_r2_bucket"},
+		"cloudflare page rule":                               {identiferType: "zone", resourceType: "cloudflare_page_rule", testdataFilename: "cloudflare_page_rule"},
+		"cloudflare ruleset (ddos_l7)":                       {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_ddos_l7"},
+		"cloudflare ruleset (http_log_custom_fields)":        {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_log_custom_fields"},
+		"cloudflare ruleset (http_ratelimit)":                {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_ratelimit"},
+		"cloudflare ruleset (http_request_cache_settings)":   {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_http_request_cache_settings"},
+		"cloudflare ruleset (http_request_firewall_custom)":  {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_request_firewall_custom"},
+		"cloudflare ruleset (http_request_firewall_managed)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_request_firewall_managed"},
+		"cloudflare ruleset (http_request_late_transform)":   {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_request_late_transform"},
+		"cloudflare ruleset (http_request_sanitize)":         {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_http_request_sanitize"},
+		"cloudflare ruleset (no configuration)":              {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_no_configuration"},
+		"cloudflare ruleset (override remapping = disabled)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_override_remapping_disabled"},
+		"cloudflare ruleset (override remapping = enabled)":  {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_override_remapping_enabled"},
+		"cloudflare ruleset (rewrite to empty query string)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_rewrite_to_empty_query_parameter"},
+		"cloudflare ruleset":                                 {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset"},
+		"cloudflare stream":                                  {identiferType: "account", resourceType: "cloudflare_stream", testdataFilename: "cloudflare_stream"},
+		"cloudflare stream keys":                             {identiferType: "account", resourceType: "cloudflare_stream_key", testdataFilename: "cloudflare_stream_key"},
+		"cloudflare stream live input":                       {identiferType: "account", resourceType: "cloudflare_stream_live_input", testdataFilename: "cloudflare_stream_live_input"},
+		"cloudflare stream webhook":                          {identiferType: "account", resourceType: "cloudflare_stream_webhook", testdataFilename: "cloudflare_stream_webhook"},
+		"cloudflare snippets":                                {identiferType: "zone", resourceType: "cloudflare_snippets", testdataFilename: "cloudflare_snippets"},
+		"cloudflare snippet rules":                           {identiferType: "zone", resourceType: "cloudflare_snippet_rules", testdataFilename: "cloudflare_snippet_rules"},
+		"cloudflare tiered cache":                            {identiferType: "zone", resourceType: "cloudflare_tiered_cache", testdataFilename: "cloudflare_tiered_cache"},
+		"cloudflare regional hostnames":                      {identiferType: "zone", resourceType: "cloudflare_regional_hostname", testdataFilename: "cloudflare_regional_hostname"},
+		"cloudflare regional tiered cache":                   {identiferType: "zone", resourceType: "cloudflare_regional_tiered_cache", testdataFilename: "cloudflare_regional_tiered_cache"},
 		// "cloudflare spectrum application":                    {identiferType: "zone", resourceType: "cloudflare_spectrum_application", testdataFilename: "cloudflare_spectrum_application"},
 		// "cloudflare teams list":                              {identiferType: "account", resourceType: "cloudflare_teams_list", testdataFilename: "cloudflare_teams_list"},
 		// "cloudflare teams location":                          {identiferType: "account", resourceType: "cloudflare_teams_location", testdataFilename: "cloudflare_teams_location"},
@@ -480,6 +480,11 @@ func TestResourceGenerationV5(t *testing.T) {
 						Transport: r,
 					},
 				))
+				apiV0, _ = cfv0.New(viper.GetString("key"), viper.GetString("email"), cfv0.HTTPClient(
+					&http.Client{
+						Transport: r,
+					},
+				))
 
 				output, _ = executeCommandC(rootCmd, "generate", "--resource-type", tc.resourceType, "--account", cloudflareTestAccountID)
 			} else {
@@ -489,6 +494,11 @@ func TestResourceGenerationV5(t *testing.T) {
 						Transport: r,
 					},
 				))
+				apiV0, _ = cfv0.New(viper.GetString("key"), viper.GetString("email"), cfv0.HTTPClient(
+					&http.Client{
+						Transport: r,
+					},
+				))
 				if tc.cliFlags != "" {
 					output, _ = executeCommandC(rootCmd, "generate",
 						"--resource-type", tc.resourceType,
diff --git a/testdata/cloudflare/v5/cloudflare_load_balancer.yaml b/testdata/cloudflare/v5/cloudflare_load_balancer.yaml
new file mode 100644
index 0000000..f9e8b51
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_load_balancer.yaml
@@ -0,0 +1,168 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/load_balancers
+    method: GET
+  response:
+    body: |
+      {
+        "errors": [],
+        "messages": [],
+        "result": [
+          {
+            "adaptive_routing": {
+              "failover_across_pools": false
+            },
+            "created_on": "2025-02-27T22:31:48.033418Z",
+            "default_pools": [
+              "c36b8a3066b335b2af7e940f2588805d"
+            ],
+            "description": "",
+            "enabled": true,
+            "fallback_pool": "c36b8a3066b335b2af7e940f2588805d",
+            "id": "fbbc2fb9b55e55c953f4aa8ffba9a908",
+            "location_strategy": {
+              "mode": "pop",
+              "prefer_ecs": "proximity"
+            },
+            "modified_on": "2025-02-27T22:31:48.033418Z",
+            "name": "tf-testacc-lb-fwwjdnedoi.terraform.cfapi.net",
+            "networks": [
+              "cloudflare"
+            ],
+            "pop_pools": {},
+            "proxied": false,
+            "random_steering": {
+              "default_weight": 1
+            },
+            "region_pools": {},
+            "session_affinity": "none",
+            "session_affinity_attributes": {
+              "drain_duration": 0,
+              "samesite": "Auto",
+              "secure": "Auto",
+              "zero_downtime_failover": "none"
+            },
+            "steering_policy": "off",
+            "ttl": 30,
+            "zone_name": "terraform.cfapi.net"
+          },
+          {
+            "adaptive_routing": {
+              "failover_across_pools": false
+            },
+            "created_on": "2025-02-27T22:34:45.092566Z",
+            "default_pools": [
+              "0ce4832a7181e0c3e2936e2c34a4687f"
+            ],
+            "description": "rules lb",
+            "enabled": true,
+            "fallback_pool": "0ce4832a7181e0c3e2936e2c34a4687f",
+            "id": "7e3fdbe63274a72f3f537247d991facc",
+            "location_strategy": {
+              "mode": "pop",
+              "prefer_ecs": "proximity"
+            },
+            "modified_on": "2025-02-27T22:34:45.092566Z",
+            "name": "tf-testacc-lb-sidcrfxrak.terraform.cfapi.net",
+            "networks": [
+              "cloudflare"
+            ],
+            "pop_pools": {},
+            "proxied": false,
+            "random_steering": {
+              "default_weight": 1
+            },
+            "region_pools": {},
+            "rules": [
+              {
+                "condition": "dns.qry.type == 28",
+                "disabled": false,
+                "name": "test rule 1",
+                "overrides": {
+                  "adaptive_routing": {
+                    "failover_across_pools": true
+                  },
+                  "location_strategy": {
+                    "mode": "resolver_ip",
+                    "prefer_ecs": "always"
+                  },
+                  "random_steering": {
+                    "default_weight": 0.2,
+                    "pool_weights": {
+                      "c29c1dc121903fbea9f0c92e83a1b1e2": 0.4
+                    }
+                  },
+                  "session_affinity_attributes": {
+                    "require_all_headers": false,
+                    "samesite": "Auto",
+                    "secure": "Auto",
+                    "zero_downtime_failover": "sticky"
+                  },
+                  "steering_policy": "geo"
+                },
+                "priority": 0
+              },
+              {
+                "condition": "dns.qry.type == 28",
+                "disabled": false,
+                "fixed_response": {
+                  "content_type": "html",
+                  "location": "www.example.com",
+                  "message_body": "hello",
+                  "status_code": 200
+                },
+                "name": "test rule 2",
+                "overrides": {},
+                "priority": 10,
+                "terminates": true
+              },
+              {
+                "condition": "dns.qry.type == 28",
+                "disabled": false,
+                "name": "test rule 3",
+                "overrides": {
+                  "region_pools": {
+                    "ENAM": [
+                      "0ce4832a7181e0c3e2936e2c34a4687f"
+                    ]
+                  }
+                },
+                "priority": 20
+              }
+            ],
+            "session_affinity": "none",
+            "session_affinity_attributes": {
+              "drain_duration": 0,
+              "samesite": "Auto",
+              "secure": "Auto",
+              "zero_downtime_failover": "none"
+            },
+            "steering_policy": "off",
+            "ttl": 30,
+            "zone_name": "terraform.cfapi.net"
+          }
+        ],
+        "result_info": {
+          "count": 2,
+          "page": 1,
+          "per_page": 9223372036854775807,
+          "total_count": 2,
+          "total_pages": 1
+        },
+        "success": true
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_load_balancer_monitor.yaml b/testdata/cloudflare/v5/cloudflare_load_balancer_monitor.yaml
new file mode 100644
index 0000000..cdb65f6
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_load_balancer_monitor.yaml
@@ -0,0 +1,133 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/accounts/f037e56e89293a057740de681ac9abbe/load_balancers/monitors
+    method: GET
+  response:
+    body: |
+      {
+        "errors": [],
+        "messages": [],
+        "result": [
+           {
+             "allow_insecure": false,
+             "created_on": "2025-03-10T20:55:04.064765Z",
+             "description": "this is a very weird load balancer",
+             "expected_body": "dead",
+             "expected_codes": "5xx",
+             "follow_redirects": false,
+             "header": {
+               "Header": [
+                 "Host"
+               ],
+               "Values": [
+                 "terraform.cfapi.net"
+               ]
+             },
+             "id": "a356070a0443978005145b9b590eba48",
+             "interval": 60,
+             "method": "HEAD",
+             "modified_on": "2025-03-10T20:55:04.064765Z",
+             "path": "/custom",
+             "port": 8080,
+             "probe_zone": "",
+             "retries": 5,
+             "timeout": 9,
+             "type": "http"
+           },
+           {
+             "allow_insecure": false,
+             "created_on": "2024-09-26T17:17:46.545449Z",
+             "description": "",
+             "expected_body": "alive",
+             "expected_codes": "2xx",
+             "follow_redirects": false,
+             "header": {},
+             "id": "d866497ec9fa9d112f34f67b5525636b",
+             "interval": 60,
+             "method": "GET",
+             "modified_on": "2024-09-26T17:17:46.545449Z",
+             "path": "/",
+             "probe_zone": "",
+             "retries": 2,
+             "timeout": 5,
+             "type": "http"
+           },
+           {
+             "allow_insecure": false,
+             "created_on": "2024-09-26T17:40:19.340928Z",
+             "description": "",
+             "expected_body": "alive",
+             "expected_codes": "2xx",
+             "follow_redirects": false,
+             "header": {},
+             "id": "5c782c80dd25db6e430f83dedde16fa3",
+             "interval": 60,
+             "method": "GET",
+             "modified_on": "2024-09-26T17:40:19.340928Z",
+             "path": "/",
+             "probe_zone": "",
+             "retries": 2,
+             "timeout": 5,
+             "type": "http"
+           },
+           {
+             "allow_insecure": false,
+             "created_on": "2024-09-26T17:41:59.623439Z",
+             "description": "",
+             "expected_body": "alive",
+             "expected_codes": "2xx",
+             "follow_redirects": false,
+             "header": {},
+             "id": "6104b948d72186596192826c2d394005",
+             "interval": 60,
+             "method": "GET",
+             "modified_on": "2024-09-26T17:41:59.623439Z",
+             "path": "/",
+             "probe_zone": "",
+             "retries": 2,
+             "timeout": 5,
+             "type": "http"
+           },
+           {
+             "allow_insecure": false,
+             "created_on": "2024-09-26T17:54:29.439442Z",
+             "description": "",
+             "expected_body": "alive",
+             "expected_codes": "2xx",
+             "follow_redirects": false,
+             "header": {},
+             "id": "ad51f15ad89f14e481753de4e7938452",
+             "interval": 60,
+             "method": "GET",
+             "modified_on": "2024-09-26T17:54:29.439442Z",
+             "path": "/",
+             "probe_zone": "",
+             "retries": 2,
+             "timeout": 5,
+             "type": "http"
+           }
+        ],
+        "result_info": {
+          "count": 40,
+          "page": 1,
+          "per_page": 9223372036854775807,
+          "total_count": 40,
+          "total_pages": 1
+        },
+        "success": true
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset.yaml b/testdata/cloudflare/v5/cloudflare_ruleset.yaml
new file mode 100644
index 0000000..d301eb9
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset.yaml
@@ -0,0 +1,187 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "description": "Created by the Cloudflare security team, this ruleset provides normalization on the URL path",
+            "id": "70339d97bdb34195bbf054b1ebe81f76",
+            "kind": "managed",
+            "last_updated": "2024-08-01T17:37:11.538019Z",
+            "name": "Cloudflare Normalization Ruleset",
+            "phase": "http_request_sanitize",
+            "version": "6"
+          },
+          {
+            "description": "Created by the Cloudflare security team, this ruleset is designed to provide fast and effective protection for all your applications. It is frequently updated to cover new vulnerabilities and reduce false positives.",
+            "id": "efb7b8c949ac4650a09736fc376e9aee",
+            "kind": "managed",
+            "last_updated": "2025-03-22T17:48:12.420395Z",
+            "name": "Cloudflare Managed Ruleset",
+            "phase": "http_request_firewall_managed",
+            "source": "firewall_managed",
+            "version": "243"
+          },
+          {
+            "description": "Cloudflare's implementation of the Open Web Application Security Project (OWASP) ModSecurity Core Rule Set. We routinely monitor for updates from OWASP based on the latest version available from the official code repository",
+            "id": "4814384a9e5d4991b9815dcfc25d2f1f",
+            "kind": "managed",
+            "last_updated": "2024-08-19T17:26:58.593021Z",
+            "name": "Cloudflare OWASP Core Ruleset",
+            "phase": "http_request_firewall_managed",
+            "source": "firewall_managed",
+            "version": "87"
+          },
+          {
+            "description": "Exposed credentials check rules",
+            "id": "c2e184081120413c86c3ab7e14069605",
+            "kind": "managed",
+            "last_updated": "2024-08-01T17:37:12.291474Z",
+            "name": "Cloudflare Exposed Credentials Check Ruleset",
+            "phase": "http_request_firewall_managed",
+            "source": "firewall_managed",
+            "version": "89"
+          },
+          {
+            "description": "Created by Cloudflare to identify data leaks generated by your origin servers. These rules run on the response phase and look into payloads for patterns of common sensitive data, including Personal Identifiable Information, Financial Information and Secrets.",
+            "id": "e22d83c647c64a3eae91b71b499d988e",
+            "kind": "managed",
+            "last_updated": "2024-08-01T17:37:04.566538Z",
+            "name": "Cloudflare Sensitive Data Detection",
+            "phase": "http_response_firewall_managed",
+            "source": "dlp",
+            "version": "111"
+          },
+          {
+            "description": "Automatic mitigation of HTTP-based DDoS attacks. Cloudflare routinely adds signatures to address new attack vectors. Additional configuration allows you to customize the sensitivity of each rule and the performed mitigation action.",
+            "id": "4d21379b4f9f4bb088e0729962c8b3cf",
+            "kind": "managed",
+            "last_updated": "2025-03-24T20:49:33.176723Z",
+            "name": "DDoS L7 ruleset",
+            "phase": "ddos_l7",
+            "version": "2774"
+          },
+          {
+            "description": "Created by the Cloudflare security team, this ruleset is designed to provide protection for free zones",
+            "id": "77454fe2d30c4220b5701f6fdfb893ba",
+            "kind": "managed",
+            "last_updated": "2025-03-22T17:48:18.057849Z",
+            "name": "Cloudflare Managed Free Ruleset",
+            "phase": "http_request_firewall_managed",
+            "source": "firewall_managed",
+            "version": "60"
+          },
+          {
+            "description": "",
+            "id": "531089b9f03945449d781dfba833bafb",
+            "kind": "zone",
+            "last_updated": "2025-03-25T22:38:12.845519Z",
+            "name": "default",
+            "phase": "http_request_dynamic_redirect",
+            "version": "3"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Cf-Auditlog-Id:
+      - 0195d08f-a147-79f2-a7e0-69c2c801fbf2
+      Connection:
+      - keep-alive
+      Content-Type:
+      - application/json; charset=UTF-8
+      Vary:
+      - Accept-Encoding
+      X-Version:
+      - 11126-5fd2b4dee189
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/531089b9f03945449d781dfba833bafb
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "description": "",
+          "id": "531089b9f03945449d781dfba833bafb",
+          "kind": "zone",
+          "last_updated": "2025-03-25T22:38:12.845519Z",
+          "name": "default",
+          "phase": "http_request_dynamic_redirect",
+          "rules": [
+            {
+              "action": "redirect",
+              "action_parameters": {
+                "from_value": {
+                  "preserve_query_string": true,
+                  "status_code": 301,
+                  "target_url": {
+                    "value": "https://example.com/foo"
+                  }
+                }
+              },
+              "enabled": true,
+              "expression": "true",
+              "id": "c4d1a4fbb1da4203a43837b4e88aace9",
+              "last_updated": "2025-03-25T22:38:12.845519Z",
+              "ref": "jacob1",
+              "version": "2"
+            },
+            {
+              "action": "redirect",
+              "action_parameters": {
+                "from_value": {
+                  "preserve_query_string": true,
+                  "status_code": 301,
+                  "target_url": {
+                    "value": "https://example.com/example1"
+                  }
+                }
+              },
+              "enabled": true,
+              "expression": "true",
+              "id": "e56201e7d0ee48cca75e28813a12e11e",
+              "last_updated": "2025-03-25T22:38:12.845519Z",
+              "ref": "jacob2",
+              "version": "3"
+            }
+          ],
+          "version": "3"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Cf-Auditlog-Id:
+      - 0195d08f-a294-7f51-a2cd-31c7c8fe558a
+      Connection:
+      - keep-alive
+      Content-Type:
+      - application/json; charset=UTF-8
+      Vary:
+      - Accept-Encoding
+      X-Version:
+      - 11126-5fd2b4dee189
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_http_request_cache_settings.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_http_request_cache_settings.yaml
new file mode 100644
index 0000000..5e42c73
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_http_request_cache_settings.yaml
@@ -0,0 +1,148 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "id": "a6905ff86d3844cebc1a88dd80c659e7",
+            "name": "default",
+            "description": "",
+            "source": "zone",
+            "kind": "zone",
+            "version": "4",
+            "last_updated": "2021-07-01T16:59:14.386598Z",
+            "phase": "http_request_cache_settings"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/a6905ff86d3844cebc1a88dd80c659e7
+    method: GET
+  response:
+    body: |
+        {
+          "result": {
+            "id": "a6905ff86d3844cebc1a88dd80c659e7",
+            "name": "default",
+            "description": "",
+            "kind": "zone",
+            "version": "3",
+            "phase": "http_request_cache_settings",
+            "rules": [
+              {
+                "id": "0f24aab3002347a9a4ac01520e6893d0",
+                "version": "3",
+                "action": "set_cache_settings",
+                "expression": "(http.host eq \"example.com\")",
+                "description": "test cache rule",
+                "last_updated": "2022-09-28T17:21:21.510301Z",
+                "ref": "0f24aab3002347a9a4ac01520e6893d0",
+                "enabled": false,
+                "action_parameters": {
+                  "cache": true,
+                  "edge_ttl": {
+                    "mode": "override_origin",
+                    "default": 30,
+                    "status_code_ttl": [
+                      {
+                        "status_code": 100,
+                        "value": 30
+                      },
+                      {
+                        "status_code_range": {
+                          "from": 100,
+                          "to": 106
+                        },
+                        "value": 5
+                      },
+                      {
+                        "status_code_range": {
+                          "from": 130,
+                          "to": 162
+                        },
+                        "value": 31536000
+                      }
+                    ]
+                  },
+                  "browser_ttl": {
+                    "mode": "respect_origin"
+                  },
+                  "serve_stale": {
+                    "disable_stale_while_updating": true
+                  },
+                  "respect_strong_etags": true,
+                  "cache_key": {
+                    "cache_by_device_type": true,
+                    "ignore_query_strings_order": false,
+                    "cache_deception_armor": true,
+                    "custom_key": {
+                      "query_string": {
+                        "exclude": "*"
+                      },
+                      "host": {
+                        "resolved": false
+                      }
+                    }
+                  },
+                  "origin_error_page_passthru": true
+                }
+              },
+              {
+                "id": "e5f1bd1386b4464aa8d726ba1e0d51ad",
+                "version": "2",
+                "action": "set_cache_settings",
+                "expression": "(http.host eq \"example.com\")",
+                "description": "/status/202",
+                "last_updated": "2022-09-21T16:36:00.999083Z",
+                "ref": "e5f1bd1386b4464aa8d726ba1e0d51ad",
+                "enabled": true,
+                "action_parameters": {
+                  "cache": false,
+                  "edge_ttl": {
+                    "mode": "override_origin",
+                    "default": 60
+                  }
+                }
+              }
+            ],
+            "last_updated": "2022-09-28T17:21:21.510301Z"
+          },
+          "success": true,
+          "errors": [],
+          "messages": []
+        }
+
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_override_remapping_disabled.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_override_remapping_disabled.yaml
new file mode 100644
index 0000000..f6215d8
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_override_remapping_disabled.yaml
@@ -0,0 +1,150 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "id": "a6905ff86d3844cebc1a88dd80c659e7",
+            "name": "Bot Fight Mode for Likely Bots",
+            "description": "",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "4",
+            "last_updated": "2021-07-01T16:59:14.386598Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "48ba18287c544bd7bdbe842a294f1ae2",
+            "name": "Bot Fight Mode for Definite Bots",
+            "description": "",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "4",
+            "last_updated": "2021-07-01T16:59:17.970712Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "4c971a697dd249939460f4520dcd7184",
+            "name": "zone",
+            "description": "",
+            "source": "firewall_managed",
+            "kind": "zone",
+            "version": "2",
+            "last_updated": "2021-09-03T06:42:41.341405Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "c2e184081120413c86c3ab7e14069605",
+            "name": "Cloudflare Exposed Credentials Check Ruleset",
+            "description": "Exposed credentials check rules",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "32",
+            "last_updated": "2021-09-06T16:39:15.601436Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "efb7b8c949ac4650a09736fc376e9aee",
+            "name": "Cloudflare Managed Ruleset",
+            "description": "Created by the Cloudflare security team, this ruleset is designed to provide fast and effective protection for all your applications. It is frequently updated to cover new vulnerabilities and reduce false positives.",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "30",
+            "last_updated": "2021-09-06T16:39:16.550214Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "4814384a9e5d4991b9815dcfc25d2f1f",
+            "name": "Cloudflare OWASP Core Ruleset",
+            "description": "Cloudflare's implementation of the Open Web Application Security Project (OWASP) ModSecurity Core Rule Set. We routinely monitor for updates from OWASP based on the latest version available from the official code repository",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "29",
+            "last_updated": "2021-09-06T16:39:18.773224Z",
+            "phase": "http_request_firewall_managed"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/4c971a697dd249939460f4520dcd7184
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "4c971a697dd249939460f4520dcd7184",
+          "name": "zone",
+          "description": "",
+          "source": "firewall_managed",
+          "kind": "zone",
+          "version": "2",
+          "rules": [
+            {
+              "action": "execute",
+              "action_parameters": {
+                "id": "efb7b8c949ac4650a09736fc376e9aee",
+                "version": "latest",
+                "overrides": {
+                  "action": "log",
+                  "enabled": false,
+                  "categories": [
+                    {
+                      "category": "paranoia-level-2",
+                      "enabled": false
+                    }
+                  ],
+                  "rules": [
+                    {
+                      "id": "6179ae15870a4bb7b2d480d4843b323c",
+                      "enabled": false
+                    }
+                  ]
+                }
+              },
+              "expression": "(http.cookie eq \"jb_testing=true\")",
+              "description": "zone",
+              "last_updated": "2021-09-03T06:42:41.341405Z",
+              "enabled": false
+            }
+          ],
+          "last_updated": "2021-09-03T06:42:41.341405Z",
+          "phase": "http_request_firewall_managed"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_override_remapping_enabled.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_override_remapping_enabled.yaml
new file mode 100644
index 0000000..9eb12e5
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_override_remapping_enabled.yaml
@@ -0,0 +1,150 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "id": "a6905ff86d3844cebc1a88dd80c659e7",
+            "name": "Bot Fight Mode for Likely Bots",
+            "description": "",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "4",
+            "last_updated": "2021-07-01T16:59:14.386598Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "48ba18287c544bd7bdbe842a294f1ae2",
+            "name": "Bot Fight Mode for Definite Bots",
+            "description": "",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "4",
+            "last_updated": "2021-07-01T16:59:17.970712Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "4c971a697dd249939460f4520dcd7184",
+            "name": "zone",
+            "description": "",
+            "source": "firewall_managed",
+            "kind": "zone",
+            "version": "2",
+            "last_updated": "2021-09-03T06:42:41.341405Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "c2e184081120413c86c3ab7e14069605",
+            "name": "Cloudflare Exposed Credentials Check Ruleset",
+            "description": "Exposed credentials check rules",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "32",
+            "last_updated": "2021-09-06T16:39:15.601436Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "efb7b8c949ac4650a09736fc376e9aee",
+            "name": "Cloudflare Managed Ruleset",
+            "description": "Created by the Cloudflare security team, this ruleset is designed to provide fast and effective protection for all your applications. It is frequently updated to cover new vulnerabilities and reduce false positives.",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "30",
+            "last_updated": "2021-09-06T16:39:16.550214Z",
+            "phase": "http_request_firewall_managed"
+          },
+          {
+            "id": "4814384a9e5d4991b9815dcfc25d2f1f",
+            "name": "Cloudflare OWASP Core Ruleset",
+            "description": "Cloudflare's implementation of the Open Web Application Security Project (OWASP) ModSecurity Core Rule Set. We routinely monitor for updates from OWASP based on the latest version available from the official code repository",
+            "source": "firewall_managed",
+            "kind": "managed",
+            "version": "29",
+            "last_updated": "2021-09-06T16:39:18.773224Z",
+            "phase": "http_request_firewall_managed"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/4c971a697dd249939460f4520dcd7184
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "4c971a697dd249939460f4520dcd7184",
+          "name": "zone",
+          "description": "",
+          "source": "firewall_managed",
+          "kind": "zone",
+          "version": "2",
+          "rules": [
+            {
+              "action": "execute",
+              "action_parameters": {
+                "id": "efb7b8c949ac4650a09736fc376e9aee",
+                "version": "latest",
+                "overrides": {
+                  "action": "log",
+                  "enabled": true,
+                  "categories": [
+                    {
+                      "category": "paranoia-level-2",
+                      "enabled": true
+                    }
+                  ],
+                  "rules": [
+                    {
+                      "id": "6179ae15870a4bb7b2d480d4843b323c",
+                      "enabled": true
+                    }
+                  ]
+                }
+              },
+              "expression": "(http.cookie eq \"jb_testing=true\")",
+              "description": "zone",
+              "last_updated": "2021-09-03T06:42:41.341405Z",
+              "enabled": false
+            }
+          ],
+          "last_updated": "2021-09-03T06:42:41.341405Z",
+          "phase": "http_request_firewall_managed"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone.yaml
new file mode 100644
index 0000000..8b73de9
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone.yaml
@@ -0,0 +1,411 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "id": "a624c23f94c84994815636e827d17937",
+            "name": "Zone sanitize ruleset",
+            "description": "",
+            "kind": "zone",
+            "version": "3",
+            "last_updated": "2021-08-19T23:41:34.985519Z",
+            "phase": "http_request_sanitize"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/a624c23f94c84994815636e827d17937
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "a624c23f94c84994815636e827d17937",
+          "name": "Zone sanitize ruleset",
+          "description": "",
+          "kind": "zone",
+          "version": "3",
+          "rules": [
+            {
+              "id": "0789dc4343054d1e981f8c44bedc6fbd",
+              "version": "1",
+              "action": "execute",
+              "action_parameters": {
+                "id": "70339d97bdb34195bbf054b1ebe81f76",
+                "version": "latest",
+                "overrides": {
+                  "rules": [
+                    {
+                      "id": "78723a9e0c7c4c6dbec5684cb766231d",
+                      "enabled": true
+                    }
+                  ]
+                }
+              },
+              "expression": "true",
+              "last_updated": "2021-08-19T23:41:34.985519Z",
+              "ref": "0789dc4343054d1e981f8c44bedc6fbd",
+              "enabled": true
+            }
+          ],
+          "last_updated": "2021-08-19T23:41:34.985519Z",
+          "phase": "http_request_sanitize"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/bf47a1e2d1f1402aa85eb8f507e3ff5b
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "bf47a1e2d1f1402aa85eb8f507e3ff5b",
+          "name": "default",
+          "description": "",
+          "source": "rate_limit",
+          "kind": "zone",
+          "version": "1",
+          "rules": [
+            {
+              "id": "549e64153ff14d2cb5a5ef88c1f5bdbc",
+              "version": "1",
+              "action": "block",
+              "ratelimit": {
+                "characteristics": [
+                  "ip.src",
+                  "cf.colo.id"
+                ],
+                "period": 60,
+                "requests_per_period": 100,
+                "mitigation_timeout": 30,
+                "mitigation_expression": ""
+              },
+              "expression": "(http.cookie eq \"namwe=value\")",
+              "description": "fwewe",
+              "last_updated": "2021-08-29T21:59:21.447624Z",
+              "ref": "549e64153ff14d2cb5a5ef88c1f5bdbc",
+              "enabled": false
+            }
+          ],
+          "last_updated": "2021-08-29T21:59:21.447624Z",
+          "phase": "http_ratelimit"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/76d07b645c674faba69eff8d8451992c
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "76d07b645c674faba69eff8d8451992c",
+          "name": "zone",
+          "description": "",
+          "kind": "zone",
+          "version": "1",
+          "rules": [
+            {
+              "id": "c6893ad10fb344e9b8be3c0c3575adc9",
+              "version": "1",
+              "action": "execute",
+              "action_parameters": {
+                "id": "4d21379b4f9f4bb088e0729962c8b3cf",
+                "version": "latest",
+                "overrides": {
+                  "sensitivity_level": "medium"
+                }
+              },
+              "expression": "true",
+              "description": "zone",
+              "last_updated": "2021-08-30T02:38:50.39057Z",
+              "ref": "c6893ad10fb344e9b8be3c0c3575adc9",
+              "enabled": true
+            }
+          ],
+          "last_updated": "2021-08-30T02:38:50.39057Z",
+          "phase": "ddos_l7"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/4c971a697dd249939460f4520dcd7184
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "4c971a697dd249939460f4520dcd7184",
+          "name": "zone",
+          "description": "",
+          "source": "firewall_managed",
+          "kind": "zone",
+          "version": "2",
+          "rules": [
+            {
+              "id": "6c41b21b852a4c89a0eaaf5a7ac560a8",
+              "version": "2",
+              "action": "execute",
+              "action_parameters": {
+                "id": "efb7b8c949ac4650a09736fc376e9aee",
+                "version": "latest",
+                "overrides": {
+                  "rules": [
+                    {
+                      "id": "5de7edfa648c4d6891dc3e7f84534ffa",
+                      "action": "block"
+                    },
+                    {
+                      "id": "d52aa57408a144afa35e0fd96e3897dc",
+                      "action": "block"
+                    },
+                    {
+                      "id": "7994335d116849f7a0ab6b771d1d0db7",
+                      "action": "block"
+                    },
+                    {
+                      "id": "20e34d3164a340dbb5c5d29203ccff90",
+                      "action": "block"
+                    },
+                    {
+                      "id": "8d9f209f35df412ba4bafe5156335ab1",
+                      "action": "block"
+                    },
+                    {
+                      "id": "8840c3fa2c7947f6b10176ceb8f65558",
+                      "action": "block"
+                    },
+                    {
+                      "id": "48e06376fc6347c0bf08b8ccf82d008b",
+                      "action": "block"
+                    },
+                    {
+                      "id": "8ea0937695984040b528c80a4e6df495",
+                      "action": "block"
+                    },
+                    {
+                      "id": "b777ce009bb346b39be4886055a71165",
+                      "action": "block"
+                    },
+                    {
+                      "id": "cb5b6de178d3488d8649da8608b7b3a2",
+                      "action": "block"
+                    },
+                    {
+                      "id": "390b6273c8dc4366b36e52fc6f35c356",
+                      "action": "block"
+                    },
+                    {
+                      "id": "8ac6964456494da6b098a93c35f86fc9",
+                      "action": "block"
+                    },
+                    {
+                      "id": "5ac122b3972c4247a247f3271045f374",
+                      "action": "block"
+                    },
+                    {
+                      "id": "b1efd337665d49f5950f892971120c4b",
+                      "action": "block"
+                    },
+                    {
+                      "id": "34158d546873469a8f8ccee19139627b",
+                      "action": "block"
+                    }
+                  ]
+                }
+              },
+              "expression": "(http.cookie eq \"jb_testing=true\")",
+              "description": "zone",
+              "last_updated": "2021-09-03T06:42:41.341405Z",
+              "ref": "6c41b21b852a4c89a0eaaf5a7ac560a8",
+              "enabled": false
+            }
+          ],
+          "last_updated": "2021-09-03T06:42:41.341405Z",
+          "phase": "http_request_firewall_managed"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/d1b807cb62c34dbc9c5f0315d5f9c299
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "d1b807cb62c34dbc9c5f0315d5f9c299",
+          "name": "default",
+          "description": "",
+          "kind": "zone",
+          "version": "4",
+          "rules": [
+            {
+              "id": "e5b61605d6cf4ce08f729c17d42d76ef",
+              "version": "1",
+              "action": "rewrite",
+              "action_parameters": {
+                "headers": {
+                  "example-http-header-1": {
+                    "operation": "remove"
+                  },
+                  "example-http-header-2": {
+                    "operation": "remove"
+                  },
+                  "example-http-header-3": {
+                    "operation": "set",
+                    "value": "space-header",
+                    "expression": "(ip.geoip.continent eq \"pluto\")"
+                  }
+                },
+                "uri": {
+                  "path": {
+                    "value": "/aquarii_b"
+                  }
+                }
+              },
+              "expression": "(http.request.uri.path eq \"example.com\")",
+              "description": "test transform",
+              "last_updated": "2022-02-07T16:58:54.317608Z",
+              "ref": "e5b61605d6cf4ce08f729c17d42d76ef",
+              "enabled": true
+            },
+            {
+              "id": "8ec764cf386940c89dd83dbab7bb4c16",
+              "version": "1",
+              "action": "rewrite",
+              "action_parameters": {
+                "headers": {
+                  "example-http-static-header-1": {
+                    "operation": "set",
+                    "value": "my-http-header-1",
+                    "expression": "(ip.geoip.continent eq \"T1\")"
+                  }
+                }
+              },
+              "expression": "(http.request.uri.path eq \"example.com\")",
+              "description": "test transform set",
+              "last_updated": "2022-02-07T16:58:54.317608Z",
+              "ref": "8ec764cf386940c89dd83dbab7bb4c16",
+              "enabled": true
+            },
+            {
+              "id": "d0f1b4fdb4234adf9c6de9b614424836",
+              "version": "1",
+              "action": "rewrite",
+              "action_parameters": {
+                "uri": {
+                  "path": {
+                    "value": "/spaceship"
+                  }
+                }
+              },
+              "expression": "(http.request.uri.path eq \"pumpkin.com\")",
+              "description": "test uri rewrite set",
+              "last_updated": "2022-05-07T16:58:54.317608Z",
+              "ref": "d0f1b4fdb4234adf9c6de9b614424836",
+              "enabled": false
+            }
+          ],
+          "last_updated": "2022-02-07T16:58:54.317608Z",
+          "phase": "http_request_late_transform"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone_ddos_l7.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone_ddos_l7.yaml
new file mode 100644
index 0000000..ec7a42f
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone_ddos_l7.yaml
@@ -0,0 +1,88 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+           {
+            "id": "76d07b645c674faba69eff8d8451992c",
+            "name": "zone",
+            "description": "",
+            "kind": "zone",
+            "version": "1",
+            "last_updated": "2021-08-30T02:38:50.39057Z",
+            "phase": "ddos_l7"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/76d07b645c674faba69eff8d8451992c
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "76d07b645c674faba69eff8d8451992c",
+          "name": "zone",
+          "description": "",
+          "kind": "zone",
+          "version": "1",
+          "rules": [
+            {
+              "id": "c6893ad10fb344e9b8be3c0c3575adc9",
+              "version": "1",
+              "action": "execute",
+              "action_parameters": {
+                "id": "4d21379b4f9f4bb088e0729962c8b3cf",
+                "version": "latest",
+                "overrides": {
+                  "sensitivity_level": "medium"
+                }
+              },
+              "expression": "true",
+              "description": "zone",
+              "last_updated": "2021-08-30T02:38:50.39057Z",
+              "ref": "c6893ad10fb344e9b8be3c0c3575adc9",
+              "enabled": true
+            }
+          ],
+          "last_updated": "2021-08-30T02:38:50.39057Z",
+          "phase": "ddos_l7"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_log_custom_fields.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_log_custom_fields.yaml
new file mode 100644
index 0000000..7f1ddcc
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_log_custom_fields.yaml
@@ -0,0 +1,107 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+           {
+            "id": "4b9724cc601c443c9dfa506d8b566dc2",
+            "name": "zone",
+            "description": "",
+            "kind": "zone",
+            "version": "1",
+            "last_updated": "2021-08-30T02:38:50.39057Z",
+            "phase": "http_log_custom_fields"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/4b9724cc601c443c9dfa506d8b566dc2
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "4b9724cc601c443c9dfa506d8b566dc2",
+          "name": "zone",
+          "description": "",
+          "kind": "zone",
+          "version": "1",
+          "rules": [
+            {
+              "id": "17a0d1e23a3444ccbd5e58fc7793649a",
+              "version": "1",
+              "action": "log_custom_field",
+              "expression": "true",
+              "description": "zone",
+              "last_updated": "2022-07-22T12:34:45.479429Z",
+              "ref": "17a0d1e23a3444ccbd5e58fc7793649a",
+              "enabled": true,
+              "action_parameters": {
+                "cookie_fields": [
+                  {
+                    "name": "cookie"
+                  },
+                  {
+                    "name": "fields"
+                  }
+                ],
+                "request_fields": [
+                  {
+                    "name": "request"
+                  },
+                  {
+                    "name": "fields"
+                  }
+                ],
+                "response_fields": [
+                  {
+                    "name": "response"
+                  },
+                  {
+                    "name": "fields"
+                  }
+                ]
+              }
+            }
+          ],
+          "last_updated": "2021-08-30T02:38:50.39057Z",
+          "phase": "http_log_custom_fields"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_ratelimit.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_ratelimit.yaml
new file mode 100644
index 0000000..8a0cf9a
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_ratelimit.yaml
@@ -0,0 +1,94 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "id": "bf47a1e2d1f1402aa85eb8f507e3ff5b",
+            "name": "default",
+            "description": "",
+            "source": "rate_limit",
+            "kind": "zone",
+            "version": "1",
+            "last_updated": "2021-08-29T21:59:21.447624Z",
+            "phase": "http_ratelimit"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/bf47a1e2d1f1402aa85eb8f507e3ff5b
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "bf47a1e2d1f1402aa85eb8f507e3ff5b",
+          "name": "default",
+          "description": "",
+          "source": "rate_limit",
+          "kind": "zone",
+          "version": "1",
+          "rules": [
+            {
+              "id": "549e64153ff14d2cb5a5ef88c1f5bdbc",
+              "version": "1",
+              "action": "block",
+              "ratelimit": {
+                "characteristics": [
+                  "ip.src",
+                  "cf.colo.id"
+                ],
+                "period": 60,
+                "requests_per_period": 100,
+                "mitigation_timeout": 30,
+                "mitigation_expression": "",
+                "requests_to_origin": true
+              },
+              "expression": "(http.cookie eq \"namwe=value\")",
+              "description": "fwewe",
+              "last_updated": "2021-08-29T21:59:21.447624Z",
+              "ref": "549e64153ff14d2cb5a5ef88c1f5bdbc",
+              "enabled": false
+            }
+          ],
+          "last_updated": "2021-08-29T21:59:21.447624Z",
+          "phase": "http_ratelimit"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_firewall_custom.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_firewall_custom.yaml
new file mode 100644
index 0000000..bad5c8c
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_firewall_custom.yaml
@@ -0,0 +1,122 @@
+---
+version: 1
+interactions:
+  - request:
+      body: ""
+      form: {}
+      headers:
+        Content-Type:
+          - application/json
+      url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+      method: GET
+    response:
+      body: |
+        {
+          "result": [
+            {
+              "id": "4c971a697dd249939460f4520dcd7184",
+              "name": "default",
+              "description": "",
+              "source": "firewall_custom",
+              "kind": "zone",
+              "version": "1",
+              "last_updated": "2021-07-01T16:59:14.386598Z",
+              "phase": "http_request_firewall_custom"
+            }
+          ],
+          "success": true,
+          "errors": [],
+          "messages": []
+        }
+      headers:
+        Content-Type:
+          - application/json
+        Vary:
+          - Accept-Encoding
+      status: 200 OK
+      code: 200
+      duration: ""
+  - request:
+      body: ""
+      form: {}
+      headers:
+        Content-Type:
+          - application/json
+      url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/4c971a697dd249939460f4520dcd7184
+      method: GET
+    response:
+      body: |
+        {
+          "result": {
+            "id": "4c971a697dd249939460f4520dcd7184",
+            "name": "zone",
+            "description": "",
+            "source": "firewall_custom",
+            "kind": "zone",
+            "version": "2",
+            "rules": [
+              {
+                "id": "88dcb30401e348ba9e1352c2598f2a4c",
+                "version": "2",
+                "action": "skip",
+                "expression": "(http.host eq \"test.example.com\")",
+                "description": "test.example.com",
+                "last_updated": "2022-11-24T14:24:14.756247Z",
+                "ref": "88dcb30401e348ba9e1352c2598f2a4c",
+                "enabled": true,
+                "logging": {
+                  "enabled": true
+                },
+                "action_parameters": {
+                  "ruleset": "current",
+                  "phases": [
+                    "http_ratelimit",
+                    "http_request_firewall_managed"
+                  ],
+                  "products": [
+                    "zoneLockdown",
+                    "uaBlock",
+                    "bic",
+                    "hot",
+                    "securityLevel",
+                    "rateLimit",
+                    "waf"
+                  ]
+                }
+              },
+              {
+                "id": "b3cc5e4cc6604f9d90a6a106df867760",
+                "version": "29",
+                "action": "challenge",
+                "expression": "(cf.bot_management.score eq 50 and cf.bot_management.static_resource)",
+                "description": "customRule-test",
+                "last_updated": "2022-11-07T19:03:05.198191Z",
+                "ref": "b3cc5e4cc6604f9d90a6a106df867760",
+                "enabled": true
+              },
+              {
+                "id": "1ecf73bdf7bd4227969a734412b13ad1",
+                "version": "7",
+                "action": "log",
+                "expression": "(cf.waf.score le 20)",
+                "description": "AWAF ML",
+                "last_updated": "2022-12-09T16:53:19.003821Z",
+                "ref": "1ecf73bdf7bd4227969a734412b13ad1",
+                "enabled": false
+              }
+            ],
+            "last_updated": "2021-09-03T06:42:41.341405Z",
+            "phase": "http_request_firewall_custom"
+          },
+          "success": true,
+          "errors": [],
+          "messages": []
+        }
+      headers:
+        Content-Type:
+          - application/json
+        Vary:
+          - Accept-Encoding
+      status: 200 OK
+      code: 200
+      duration: ""
\ No newline at end of file
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_firewall_managed.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_firewall_managed.yaml
new file mode 100644
index 0000000..31338de
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_firewall_managed.yaml
@@ -0,0 +1,287 @@
+---
+version: 1
+interactions:
+  - request:
+      body: ""
+      form: {}
+      headers:
+        Content-Type:
+          - application/json
+      url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+      method: GET
+    response:
+      body: |
+        {
+          "result": [
+            {
+              "id": "a6905ff86d3844cebc1a88dd80c659e7",
+              "name": "Bot Fight Mode for Likely Bots",
+              "description": "",
+              "source": "firewall_managed",
+              "kind": "managed",
+              "version": "4",
+              "last_updated": "2021-07-01T16:59:14.386598Z",
+              "phase": "http_request_firewall_managed"
+            },
+            {
+              "id": "48ba18287c544bd7bdbe842a294f1ae2",
+              "name": "Bot Fight Mode for Definite Bots",
+              "description": "",
+              "source": "firewall_managed",
+              "kind": "managed",
+              "version": "4",
+              "last_updated": "2021-07-01T16:59:17.970712Z",
+              "phase": "http_request_firewall_managed"
+            },
+            {
+              "id": "4c971a697dd249939460f4520dcd7184",
+              "name": "zone",
+              "description": "",
+              "source": "firewall_managed",
+              "kind": "zone",
+              "version": "2",
+              "last_updated": "2021-09-03T06:42:41.341405Z",
+              "phase": "http_request_firewall_managed"
+            },
+            {
+              "id": "c2e184081120413c86c3ab7e14069605",
+              "name": "Cloudflare Exposed Credentials Check Ruleset",
+              "description": "Exposed credentials check rules",
+              "source": "firewall_managed",
+              "kind": "managed",
+              "version": "32",
+              "last_updated": "2021-09-06T16:39:15.601436Z",
+              "phase": "http_request_firewall_managed"
+            },
+            {
+              "id": "efb7b8c949ac4650a09736fc376e9aee",
+              "name": "Cloudflare Managed Ruleset",
+              "description": "Created by the Cloudflare security team, this ruleset is designed to provide fast and effective protection for all your applications. It is frequently updated to cover new vulnerabilities and reduce false positives.",
+              "source": "firewall_managed",
+              "kind": "managed",
+              "version": "30",
+              "last_updated": "2021-09-06T16:39:16.550214Z",
+              "phase": "http_request_firewall_managed"
+            },
+            {
+              "id": "4814384a9e5d4991b9815dcfc25d2f1f",
+              "name": "Cloudflare OWASP Core Ruleset",
+              "description": "Cloudflare's implementation of the Open Web Application Security Project (OWASP) ModSecurity Core Rule Set. We routinely monitor for updates from OWASP based on the latest version available from the official code repository",
+              "source": "firewall_managed",
+              "kind": "managed",
+              "version": "29",
+              "last_updated": "2021-09-06T16:39:18.773224Z",
+              "phase": "http_request_firewall_managed"
+            }
+          ],
+          "success": true,
+          "errors": [],
+          "messages": []
+        }
+      headers:
+        Content-Type:
+          - application/json
+        Vary:
+          - Accept-Encoding
+      status: 200 OK
+      code: 200
+      duration: ""
+  - request:
+      body: ""
+      form: {}
+      headers:
+        Content-Type:
+          - application/json
+      url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/4c971a697dd249939460f4520dcd7184
+      method: GET
+    response:
+      body: |
+        {
+          "result": {
+            "id": "4c971a697dd249939460f4520dcd7184",
+            "name": "zone",
+            "description": "",
+            "source": "firewall_managed",
+            "kind": "zone",
+            "version": "2",
+            "rules": [
+              {
+                "action": "execute",
+                "action_parameters": {
+                  "id": "efb7b8c949ac4650a09736fc376e9aee",
+                  "version": "latest",
+                  "overrides": {
+                    "rules": [
+                      {
+                        "id": "5de7edfa648c4d6891dc3e7f84534ffa",
+                        "action": "block"
+                      },
+                      {
+                        "id": "d52aa57408a144afa35e0fd96e3897dc",
+                        "action": "block"
+                      },
+                      {
+                        "id": "7994335d116849f7a0ab6b771d1d0db7",
+                        "action": "block"
+                      },
+                      {
+                        "id": "20e34d3164a340dbb5c5d29203ccff90",
+                        "action": "block"
+                      },
+                      {
+                        "id": "8d9f209f35df412ba4bafe5156335ab1",
+                        "action": "block"
+                      },
+                      {
+                        "id": "8840c3fa2c7947f6b10176ceb8f65558",
+                        "action": "block"
+                      },
+                      {
+                        "id": "48e06376fc6347c0bf08b8ccf82d008b",
+                        "action": "block"
+                      },
+                      {
+                        "id": "8ea0937695984040b528c80a4e6df495",
+                        "action": "block"
+                      },
+                      {
+                        "id": "b777ce009bb346b39be4886055a71165",
+                        "action": "block"
+                      },
+                      {
+                        "id": "cb5b6de178d3488d8649da8608b7b3a2",
+                        "action": "block"
+                      },
+                      {
+                        "id": "390b6273c8dc4366b36e52fc6f35c356",
+                        "action": "block"
+                      },
+                      {
+                        "id": "8ac6964456494da6b098a93c35f86fc9",
+                        "action": "block"
+                      },
+                      {
+                        "id": "5ac122b3972c4247a247f3271045f374",
+                        "action": "block"
+                      },
+                      {
+                        "id": "b1efd337665d49f5950f892971120c4b",
+                        "action": "block"
+                      },
+                      {
+                        "id": "34158d546873469a8f8ccee19139627b",
+                        "action": "block"
+                      }
+                    ]
+                  }
+                },
+                "expression": "(http.cookie eq \"jb_testing=true\")",
+                "description": "zone",
+                "last_updated": "2021-09-03T06:42:41.341405Z",
+                "enabled": false
+              },
+              {
+                "id": "d189267a8dc943769d0000c3dcb400eb",
+                "version": "1",
+                "action": "skip",
+                "expression": "(http.request.method eq \"POST\" and http.request.uri.path eq \"/api/v1/identity\")",
+                "description": "Bypass managed OWSAP SQL Injection rules for /api/v1/identity",
+                "last_updated": "2023-05-12T08:23:03.177093Z",
+                "ref": "d189267a8dc943769d0000c3dcb400eb",
+                "enabled": true,
+                "logging": {
+                  "enabled": true
+                },
+                "action_parameters": {
+                  "rules": {
+                    "4814384a9e5d4991b9815dcfc25d2f1f": [
+                      "37da7855d2f94f69865365d894a556a4",
+                      "6afe6795ee6a48d6a1dfe59255395a78",
+                      "5a6f5a57cde8428ab0668ce17cdec0c8",
+                      "5e4903d6afa841c9b88b96203297003f",
+                      "2380cd409b604c2a9273042f3eb29c4e",
+                      "f5aebedc99a14c8d9e8cfa2ce5f94216",
+                      "edf8c37cc81747d382690b3c77e82ce4",
+                      "1129dfb383bb42e48466488cf3b37cb1"
+                    ]
+                  }
+                }
+              }
+            ],
+            "last_updated": "2021-09-03T06:42:41.341405Z",
+            "phase": "http_request_firewall_managed"
+          },
+          "success": true,
+          "errors": [],
+          "messages": []
+        }
+      headers:
+        Content-Type:
+          - application/json
+        Vary:
+          - Accept-Encoding
+      status: 200 OK
+      code: 200
+      duration: ""
+  - request:
+      body: ""
+      form: {}
+      headers:
+        Content-Type:
+          - application/json
+      url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/4814384a9e5d4991b9815dcfc25d2f1f
+      method: GET
+    response:
+      body: |
+        {
+          "result": {
+            "id": "4814384a9e5d4991b9815dcfc25d2f1f",
+            "name": "zone",
+            "description": "",
+            "source": "firewall_managed",
+            "kind": "zone",
+            "version": "2",
+            "rules": [
+              {
+                "id": "d189267a8dc943769d0000c3dcb400eb",
+                "version": "1",
+                "action": "skip",
+                "expression": "(http.request.method eq \"POST\" and http.request.uri.path eq \"/api/v1/identity\")",
+                "description": "Bypass managed OWSAP SQL Injection rules for /api/v1/identity",
+                "last_updated": "2023-05-12T08:23:03.177093Z",
+                "ref": "d189267a8dc943769d0000c3dcb400eb",
+                "enabled": true,
+                "logging": {
+                  "enabled": true
+                },
+                "action_parameters": {
+                  "rules": {
+                    "4814384a9e5d4991b9815dcfc25d2f1f": [
+                      "37da7855d2f94f69865365d894a556a4",
+                      "6afe6795ee6a48d6a1dfe59255395a78",
+                      "5a6f5a57cde8428ab0668ce17cdec0c8",
+                      "5e4903d6afa841c9b88b96203297003f",
+                      "2380cd409b604c2a9273042f3eb29c4e",
+                      "f5aebedc99a14c8d9e8cfa2ce5f94216",
+                      "edf8c37cc81747d382690b3c77e82ce4",
+                      "1129dfb383bb42e48466488cf3b37cb1"
+                    ]
+                  }
+                }
+              }
+            ],
+            "last_updated": "2021-09-03T06:42:41.341405Z",
+            "phase": "http_request_firewall_managed"
+          },
+          "success": true,
+          "errors": [],
+          "messages": []
+        }
+      headers:
+        Content-Type:
+          - application/json
+        Vary:
+          - Accept-Encoding
+      status: 200 OK
+      code: 200
+      duration: ""
\ No newline at end of file
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_late_transform.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_late_transform.yaml
new file mode 100644
index 0000000..260e28d
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_late_transform.yaml
@@ -0,0 +1,135 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "id": "d1b807cb62c34dbc9c5f0315d5f9c299",
+            "name": "default",
+            "description": "",
+            "kind": "zone",
+            "version": "4",
+            "last_updated": "2022-02-07T16:58:54.317608Z",
+            "phase": "http_request_late_transform"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/d1b807cb62c34dbc9c5f0315d5f9c299
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "d1b807cb62c34dbc9c5f0315d5f9c299",
+          "name": "default",
+          "description": "",
+          "kind": "zone",
+          "version": "4",
+          "rules": [
+            {
+              "id": "e5b61605d6cf4ce08f729c17d42d76ef",
+              "version": "1",
+              "action": "rewrite",
+              "action_parameters": {
+                "headers": {
+                  "example-http-header-1": {
+                    "operation": "remove"
+                  },
+                  "example-http-header-2": {
+                    "operation": "remove"
+                  },
+                  "example-http-header-3": {
+                    "operation": "set",
+                    "expression": "(ip.geoip.continent eq \"pluto\")"
+                  }
+                },
+                "uri": {
+                  "path": {
+                    "value": "/aquarii_b"
+                  }
+                }
+              },
+              "expression": "(http.request.uri.path eq \"example.com\")",
+              "description": "test transform",
+              "last_updated": "2022-02-07T16:58:54.317608Z",
+              "ref": "e5b61605d6cf4ce08f729c17d42d76ef",
+              "enabled": true
+            },
+            {
+              "id": "8ec764cf386940c89dd83dbab7bb4c16",
+              "version": "1",
+              "action": "rewrite",
+              "action_parameters": {
+                "headers": {
+                  "example-http-static-header-1": {
+                    "operation": "set",
+                    "value": "my-http-header-1"
+                  }
+                }
+              },
+              "expression": "(http.request.uri.path eq \"example.com\")",
+              "description": "test transform set",
+              "last_updated": "2022-02-07T16:58:54.317608Z",
+              "ref": "8ec764cf386940c89dd83dbab7bb4c16",
+              "enabled": true
+            },
+            {
+              "id": "d0f1b4fdb4234adf9c6de9b614424836",
+              "version": "1",
+              "action": "rewrite",
+              "action_parameters": {
+                "uri": {
+                  "path": {
+                    "value": "/spaceship"
+                  }
+                }
+              },
+              "expression": "(http.request.uri.path eq \"pumpkin.com\")",
+              "description": "test uri rewrite set",
+              "last_updated": "2022-05-07T16:58:54.317608Z",
+              "ref": "d0f1b4fdb4234adf9c6de9b614424836",
+              "enabled": false
+            }
+          ],
+          "last_updated": "2022-02-07T16:58:54.317608Z",
+          "phase": "http_request_late_transform"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_sanitize.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_sanitize.yaml
new file mode 100644
index 0000000..a4dbad0
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone_http_request_sanitize.yaml
@@ -0,0 +1,92 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "id": "a624c23f94c84994815636e827d17937",
+            "name": "Zone sanitize ruleset",
+            "description": "",
+            "kind": "zone",
+            "version": "3",
+            "last_updated": "2021-08-19T23:41:34.985519Z",
+            "phase": "http_request_sanitize"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/a624c23f94c84994815636e827d17937
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "a624c23f94c84994815636e827d17937",
+          "name": "Zone sanitize ruleset",
+          "description": "",
+          "kind": "zone",
+          "version": "3",
+          "rules": [
+            {
+              "id": "0789dc4343054d1e981f8c44bedc6fbd",
+              "version": "1",
+              "action": "execute",
+              "action_parameters": {
+                "id": "70339d97bdb34195bbf054b1ebe81f76",
+                "version": "latest",
+                "overrides": {
+                  "rules": [
+                    {
+                      "id": "78723a9e0c7c4c6dbec5684cb766231d",
+                      "enabled": true
+                    }
+                  ]
+                }
+              },
+              "expression": "true",
+              "last_updated": "2021-08-19T23:41:34.985519Z",
+              "ref": "0789dc4343054d1e981f8c44bedc6fbd",
+              "enabled": true
+            }
+          ],
+          "last_updated": "2021-08-19T23:41:34.985519Z",
+          "phase": "http_request_sanitize"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone_no_configuration.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone_no_configuration.yaml
new file mode 100644
index 0000000..ed58ae1
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone_no_configuration.yaml
@@ -0,0 +1,70 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "id": "0800fc577294c34e0b28ad2839435945",
+            "name": "default",
+            "description": "Some ruleset",
+            "kind": "zone",
+            "version": "2",
+            "last_updated": "2022-04-07T16:58:54.317608Z",
+            "phase": "http_request_late_transform"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/0800fc577294c34e0b28ad2839435945
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "a624c23f94c84994815636e827d17937",
+          "name": "defautl",
+          "description": "Zone late transform ruleset",
+          "kind": "zone",
+          "version": "3",
+          "rules": [],
+          "last_updated": "2021-08-19T23:41:34.985519Z",
+          "phase": "http_request_late_transform"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/cloudflare/v5/cloudflare_ruleset_zone_rewrite_to_empty_query_parameter.yaml b/testdata/cloudflare/v5/cloudflare_ruleset_zone_rewrite_to_empty_query_parameter.yaml
new file mode 100644
index 0000000..789f95f
--- /dev/null
+++ b/testdata/cloudflare/v5/cloudflare_ruleset_zone_rewrite_to_empty_query_parameter.yaml
@@ -0,0 +1,89 @@
+---
+version: 1
+interactions:
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
+    method: GET
+  response:
+    body: |
+      {
+        "result": [
+          {
+            "id": "c0e45d27315a4fa2bf62ffa2312f935b",
+            "name": "default",
+            "description": "",
+            "kind": "zone",
+            "version": "5",
+            "last_updated": "2023-02-16T00:26:08.978517Z",
+            "phase": "http_request_transform"
+          }
+        ],
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
+- request:
+    body: ""
+    form: {}
+    headers:
+      Content-Type:
+      - application/json
+    url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/c0e45d27315a4fa2bf62ffa2312f935b
+    method: GET
+  response:
+    body: |
+      {
+        "result": {
+          "id": "c0e45d27315a4fa2bf62ffa2312f935b",
+          "name": "default",
+          "description": "",
+          "kind": "zone",
+          "version": "5",
+          "rules": [
+            {
+              "id": "1fb6a3117e864d46bcda192d14a1e1dc",
+              "version": "5",
+              "action": "rewrite",
+              "expression": "true",
+              "description": "rewrite with no query string",
+              "last_updated": "2023-02-16T00:26:08.978517Z",
+              "ref": "1fb6a3117e864d46bcda192d14a1e1dc",
+              "enabled": true,
+              "action_parameters": {
+                "uri": {
+                  "query": {
+                    "value": ""
+                  }
+                }
+              }
+            }
+          ],
+          "last_updated": "2023-02-16T00:26:08.978517Z",
+          "phase": "http_request_transform"
+        },
+        "success": true,
+        "errors": [],
+        "messages": []
+      }
+    headers:
+      Content-Type:
+      - application/json
+      Vary:
+      - Accept-Encoding
+    status: 200 OK
+    code: 200
+    duration: ""
diff --git a/testdata/terraform/v5/cloudflare_load_balancer/test.tf b/testdata/terraform/v5/cloudflare_load_balancer/test.tf
index b62fe63..61e3a7a 100644
--- a/testdata/terraform/v5/cloudflare_load_balancer/test.tf
+++ b/testdata/terraform/v5/cloudflare_load_balancer/test.tf
@@ -1,104 +1,114 @@
-resource "cloudflare_load_balancer" "terraform_managed_resource" {
-  zone_id = "699d98642c564d2e855e9661899b7252"
-  default_pools = ["17b5962d775c646f3f9725cbc7a53df4", "9290f38c5d07c2e2f4df57b1f61d4196", "00920f38ce07c2e2f4df50b1f61d4194"]
-  fallback_pool = "fallback_pool"
-  name = "www.example.com"
+resource "cloudflare_load_balancer" "terraform_managed_resource_0" {
+  default_pools    = ["c36b8a3066b335b2af7e940f2588805d"]
+  enabled          = true
+  fallback_pool    = "c36b8a3066b335b2af7e940f2588805d"
+  name             = "tf-testacc-lb-fwwjdnedoi.terraform.cfapi.net"
+  networks         = ["cloudflare"]
+  pop_pools        = {}
+  proxied          = false
+  region_pools     = {}
+  session_affinity = "none"
+  steering_policy  = "off"
+  ttl              = 30
+  zone_id          = "0da42c8d2132a9ddaf714f9e7c920711"
   adaptive_routing = {
-    failover_across_pools = true
-  }
-  country_pools = {
-    GB = ["abd90f38ced07c2e2f4df50b1f61d4194"]
-    US = ["de90f38ced07c2e2f4df50b1f61d4194", "00920f38ce07c2e2f4df50b1f61d4194"]
+    failover_across_pools = false
   }
-  description = "Load Balancer for www.example.com"
   location_strategy = {
-    mode = "pop"
-    prefer_ecs = "always"
+    mode       = "pop"
+    prefer_ecs = "proximity"
   }
-  networks = ["string"]
-  pop_pools = {
-    LAX = ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"]
-    LHR = ["abd90f38ced07c2e2f4df50b1f61d4194", "f9138c5d07c2e2f4df57b1f61d4196"]
-    SJC = ["00920f38ce07c2e2f4df50b1f61d4194"]
-  }
-  proxied = true
   random_steering = {
-    default_weight = 0.2
-    pool_weights = {
-      "9290f38c5d07c2e2f4df57b1f61d4196" = 0.5
-      de90f38ced07c2e2f4df50b1f61d4194 = 0.3
-    }
+    default_weight = 1
+  }
+  session_affinity_attributes = {
+    drain_duration         = 0
+    samesite               = "Auto"
+    secure                 = "Auto"
+    zero_downtime_failover = "none"
   }
-  region_pools = {
-    ENAM = ["00920f38ce07c2e2f4df50b1f61d4194"]
-    WNAM = ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"]
+}
+
+resource "cloudflare_load_balancer" "terraform_managed_resource_1" {
+  default_pools    = ["0ce4832a7181e0c3e2936e2c34a4687f"]
+  description      = "rules lb"
+  enabled          = true
+  fallback_pool    = "0ce4832a7181e0c3e2936e2c34a4687f"
+  name             = "tf-testacc-lb-sidcrfxrak.terraform.cfapi.net"
+  networks         = ["cloudflare"]
+  pop_pools        = {}
+  proxied          = false
+  region_pools     = {}
+  session_affinity = "none"
+  steering_policy  = "off"
+  ttl              = 30
+  zone_id          = "0da42c8d2132a9ddaf714f9e7c920711"
+  adaptive_routing = {
+    failover_across_pools = false
+  }
+  location_strategy = {
+    mode       = "pop"
+    prefer_ecs = "proximity"
+  }
+  random_steering = {
+    default_weight = 1
   }
   rules = [{
-    condition = "http.request.uri.path contains \"/testing\""
-    disabled = true
-    fixed_response = {
-      content_type = "application/json"
-      location = "www.example.com"
-      message_body = "Testing Hello"
-      status_code = 0
-    }
-    name = "route the path /testing to testing datacenter."
+    condition = "dns.qry.type == 28"
+    disabled  = false
+    name      = "test rule 1"
     overrides = {
       adaptive_routing = {
         failover_across_pools = true
       }
-      country_pools = {
-        GB = ["abd90f38ced07c2e2f4df50b1f61d4194"]
-        US = ["de90f38ced07c2e2f4df50b1f61d4194", "00920f38ce07c2e2f4df50b1f61d4194"]
-      }
-      default_pools = ["17b5962d775c646f3f9725cbc7a53df4", "9290f38c5d07c2e2f4df57b1f61d4196", "00920f38ce07c2e2f4df50b1f61d4194"]
-      fallback_pool = "fallback_pool"
       location_strategy = {
-        mode = "pop"
+        mode       = "resolver_ip"
         prefer_ecs = "always"
       }
-      pop_pools = {
-        LAX = ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"]
-        LHR = ["abd90f38ced07c2e2f4df50b1f61d4194", "f9138c5d07c2e2f4df57b1f61d4196"]
-        SJC = ["00920f38ce07c2e2f4df50b1f61d4194"]
-      }
       random_steering = {
         default_weight = 0.2
         pool_weights = {
-          "9290f38c5d07c2e2f4df57b1f61d4196" = 0.5
-          de90f38ced07c2e2f4df50b1f61d4194 = 0.3
+          c29c1dc121903fbea9f0c92e83a1b1e2 = 0.4
         }
       }
-      region_pools = {
-        ENAM = ["00920f38ce07c2e2f4df50b1f61d4194"]
-        WNAM = ["de90f38ced07c2e2f4df50b1f61d4194", "9290f38c5d07c2e2f4df57b1f61d4196"]
-      }
-      session_affinity = "none"
       session_affinity_attributes = {
-        drain_duration = 100
-        headers = ["x"]
-        require_all_headers = true
-        samesite = "Auto"
-        secure = "Auto"
-        zero_downtime_failover = "none"
+        require_all_headers    = false
+        samesite               = "Auto"
+        secure                 = "Auto"
+        zero_downtime_failover = "sticky"
       }
-      session_affinity_ttl = 1800
-      steering_policy = "off"
-      ttl = 30
+      steering_policy = "geo"
     }
     priority = 0
+    }, {
+    condition = "dns.qry.type == 28"
+    disabled  = false
+    fixed_response = {
+      content_type = "html"
+      location     = "www.example.com"
+      message_body = "hello"
+      status_code  = 200
+    }
+    name       = "test rule 2"
+    overrides  = {}
+    priority   = 10
     terminates = true
+    }, {
+    condition = "dns.qry.type == 28"
+    disabled  = false
+    name      = "test rule 3"
+    overrides = {
+      region_pools = {
+        ENAM = ["0ce4832a7181e0c3e2936e2c34a4687f"]
+      }
+    }
+    priority = 20
   }]
-  session_affinity = "none"
   session_affinity_attributes = {
-    drain_duration = 100
-    headers = ["x"]
-    require_all_headers = true
-    samesite = "Auto"
-    secure = "Auto"
+    drain_duration         = 0
+    samesite               = "Auto"
+    secure                 = "Auto"
     zero_downtime_failover = "none"
   }
-  session_affinity_ttl = 1800
-  steering_policy = "off"
-  ttl = 30
 }
+
diff --git a/testdata/terraform/v5/cloudflare_load_balancer_monitor/test.tf b/testdata/terraform/v5/cloudflare_load_balancer_monitor/test.tf
index 2a9aa0b..a8a23b6 100644
--- a/testdata/terraform/v5/cloudflare_load_balancer_monitor/test.tf
+++ b/testdata/terraform/v5/cloudflare_load_balancer_monitor/test.tf
@@ -1,22 +1,80 @@
-resource "cloudflare_load_balancer_monitor" "terraform_managed_resource" {
-  account_id = "023e105f4ecef8ad9ca31a8372d0c353"
-  allow_insecure = true
-  consecutive_down = 0
-  consecutive_up = 0
-  description = "Login page monitor"
-  expected_body = "alive"
-  expected_codes = "2xx"
-  follow_redirects = true
+resource "cloudflare_load_balancer_monitor" "terraform_managed_resource_0" {
+  account_id       = "f037e56e89293a057740de681ac9abbe"
+  allow_insecure   = false
+  description      = "this is a very weird load balancer"
+  expected_body    = "dead"
+  expected_codes   = "5xx"
+  follow_redirects = false
   header = {
-    Host = ["example.com"]
-    X-App-ID = ["abc123"]
+    Header = ["Host"]
+    Values = ["terraform.cfapi.net"]
   }
-  interval = 0
-  method = "GET"
-  path = "/health"
-  port = 0
-  probe_zone = "example.com"
-  retries = 0
-  timeout = 0
-  type = "http"
+  interval = 60
+  method   = "HEAD"
+  path     = "/custom"
+  port     = 8080
+  retries  = 5
+  timeout  = 9
+  type     = "http"
 }
+
+resource "cloudflare_load_balancer_monitor" "terraform_managed_resource_1" {
+  account_id       = "f037e56e89293a057740de681ac9abbe"
+  allow_insecure   = false
+  expected_body    = "alive"
+  expected_codes   = "2xx"
+  follow_redirects = false
+  header           = {}
+  interval         = 60
+  method           = "GET"
+  path             = "/"
+  retries          = 2
+  timeout          = 5
+  type             = "http"
+}
+
+resource "cloudflare_load_balancer_monitor" "terraform_managed_resource_2" {
+  account_id       = "f037e56e89293a057740de681ac9abbe"
+  allow_insecure   = false
+  expected_body    = "alive"
+  expected_codes   = "2xx"
+  follow_redirects = false
+  header           = {}
+  interval         = 60
+  method           = "GET"
+  path             = "/"
+  retries          = 2
+  timeout          = 5
+  type             = "http"
+}
+
+resource "cloudflare_load_balancer_monitor" "terraform_managed_resource_3" {
+  account_id       = "f037e56e89293a057740de681ac9abbe"
+  allow_insecure   = false
+  expected_body    = "alive"
+  expected_codes   = "2xx"
+  follow_redirects = false
+  header           = {}
+  interval         = 60
+  method           = "GET"
+  path             = "/"
+  retries          = 2
+  timeout          = 5
+  type             = "http"
+}
+
+resource "cloudflare_load_balancer_monitor" "terraform_managed_resource_4" {
+  account_id       = "f037e56e89293a057740de681ac9abbe"
+  allow_insecure   = false
+  expected_body    = "alive"
+  expected_codes   = "2xx"
+  follow_redirects = false
+  header           = {}
+  interval         = 60
+  method           = "GET"
+  path             = "/"
+  retries          = 2
+  timeout          = 5
+  type             = "http"
+}
+
diff --git a/testdata/terraform/v5/cloudflare_load_balancer_pool/test.tf b/testdata/terraform/v5/cloudflare_load_balancer_pool/test.tf
index 4e6343b..a42ee78 100644
--- a/testdata/terraform/v5/cloudflare_load_balancer_pool/test.tf
+++ b/testdata/terraform/v5/cloudflare_load_balancer_pool/test.tf
@@ -1,40 +1,26 @@
-resource "cloudflare_load_balancer_pool" "terraform_managed_resource" {
-  account_id = "023e105f4ecef8ad9ca31a8372d0c353"
-  name = "primary-dc-1"
+resource "cloudflare_load_balancer_pool" "terraform_managed_resource_0" {
+  account_id      = "f037e56e89293a057740de681ac9abbe"
+  enabled         = true
+  minimum_origins = 1
+  name            = "pool1"
   origins = [{
-    address = "0.0.0.0"
+    address = "example.com"
     enabled = true
-    header = {
-      host = ["example.com"]
-    }
-    name = "app-server-1"
-    virtual_network_id = "a5624d4e-044a-4ff0-b3e1-e2465353d4b4"
-    weight = 0.6
+    name    = "example-1"
+    weight  = 1
   }]
-  description = "Primary data center - Provider XYZ"
-  enabled = false
-  latitude = 0
-  load_shedding = {
-    default_percent = 0
-    default_policy = "random"
-    session_percent = 0
-    session_policy = "hash"
-  }
-  longitude = 0
-  minimum_origins = 0
-  monitor = "monitor"
-  notification_email = "someone@example.com,sometwo@example.com"
-  notification_filter = {
-    origin = {
-      disable = true
-      healthy = true
-    }
-    pool = {
-      disable = true
-      healthy = false
-    }
-  }
-  origin_steering = {
-    policy = "random"
-  }
 }
+
+resource "cloudflare_load_balancer_pool" "terraform_managed_resource_1" {
+  account_id      = "f037e56e89293a057740de681ac9abbe"
+  enabled         = true
+  minimum_origins = 1
+  name            = "pool2"
+  origins = [{
+    address = "example.com"
+    enabled = true
+    name    = "example-2"
+    weight  = 1
+  }]
+}
+
diff --git a/testdata/terraform/v5/cloudflare_ruleset/test.tf b/testdata/terraform/v5/cloudflare_ruleset/test.tf
index 226b73e..e69de29 100644
--- a/testdata/terraform/v5/cloudflare_ruleset/test.tf
+++ b/testdata/terraform/v5/cloudflare_ruleset/test.tf
@@ -1,44 +0,0 @@
-resource "cloudflare_ruleset" "terraform_managed_resource" {
-  kind = "managed"
-  name = "My ruleset"
-  phase = "ddos_l4"
-  rules = [{
-    id = "3a03d665bac047339bb530ecb439a90d"
-    action = "block"
-    action_parameters = {
-      response = {
-        content = <<EOT
-        {
-          "success": false,
-          "error": "you have been blocked"
-        }
-        EOT
-        content_type = "application/json"
-        status_code = 400
-      }
-    }
-    description = "Block when the IP address is not 1.1.1.1"
-    enabled = true
-    exposed_credential_check = {
-      password_expression = "url_decode(http.request.body.form[\\\"password\\\"][0])"
-      username_expression = "url_decode(http.request.body.form[\\\"username\\\"][0])"
-    }
-    expression = "ip.src ne 1.1.1.1"
-    logging = {
-      enabled = true
-    }
-    ratelimit = {
-      characteristics = ["ip.src"]
-      period = 10
-      counting_expression = "http.request.body.raw eq \"abcd\""
-      mitigation_timeout = 600
-      requests_per_period = 1000
-      requests_to_origin = true
-      score_per_period = 400
-      score_response_header_name = "my-score"
-    }
-    ref = "my_ref"
-  }]
-  zone_id = "zone_id"
-  description = "My ruleset to execute managed rulesets"
-}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_http_request_cache_settings/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_http_request_cache_settings/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_http_request_cache_settings/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_http_request_cache_settings/test.tf b/testdata/terraform/v5/cloudflare_ruleset_http_request_cache_settings/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_override_remapping_disabled/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_override_remapping_disabled/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_override_remapping_disabled/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_override_remapping_disabled/test.tf b/testdata/terraform/v5/cloudflare_ruleset_override_remapping_disabled/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_override_remapping_enabled/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_override_remapping_enabled/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_override_remapping_enabled/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_override_remapping_enabled/test.tf b/testdata/terraform/v5/cloudflare_ruleset_override_remapping_enabled/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_ddos_l7/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_ddos_l7/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone_ddos_l7/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_ddos_l7/test.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_ddos_l7/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_log_custom_fields/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_log_custom_fields/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone_http_log_custom_fields/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_log_custom_fields/test.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_log_custom_fields/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_ratelimit/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_ratelimit/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone_http_ratelimit/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_ratelimit/test.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_ratelimit/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_custom/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_custom/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_custom/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_custom/test.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_custom/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_managed/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_managed/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_managed/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_managed/test.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_firewall_managed/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_late_transform/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_late_transform/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_late_transform/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_late_transform/test.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_late_transform/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_sanitize/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_sanitize/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_sanitize/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_sanitize/test.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_http_request_sanitize/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_no_configuration/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_no_configuration/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone_no_configuration/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_no_configuration/test.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_no_configuration/test.tf
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_rewrite_to_empty_query_parameter/provider.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_rewrite_to_empty_query_parameter/provider.tf
new file mode 100644
index 0000000..b28f67c
--- /dev/null
+++ b/testdata/terraform/v5/cloudflare_ruleset_zone_rewrite_to_empty_query_parameter/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+  required_providers {
+    cloudflare = {
+      source = "cloudflare/cloudflare"
+      version = "~> 5"
+    }
+  }
+}
diff --git a/testdata/terraform/v5/cloudflare_ruleset_zone_rewrite_to_empty_query_parameter/test.tf b/testdata/terraform/v5/cloudflare_ruleset_zone_rewrite_to_empty_query_parameter/test.tf
new file mode 100644
index 0000000..e69de29