mykiwi/mykiwi.blogpublic Fork 0
b9bda7a
Commits
Clone
git clone https://git.rickub.com/mykiwi/mykiwi.blog.git
git clone ssh://git@rickub.com/mykiwi/mykiwi.blog.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Migrate www redirect from Page Rules to Single Redirects

The Page Rules Edit permission only shows up in the API token builder
for account Super Administrators, which blocked provisioning with a
normal scoped token (Authentication error 10000). cloudflare_ruleset
with the http_request_dynamic_redirect phase does the same www -> apex
redirect and only needs Zone:Dynamic Redirect:Edit.
Romain Gautier committed 2026-09-18T19:58:17+02:00 Browse files
b9bda7a parent: 479f7e2
modified infra/README.md +2 -1
@@ -15,7 +15,8 @@ on.
1515
1616 Create a token at https://dash.cloudflare.com/profile/api-tokens (Custom
1717 Token, scoped to the `mykiwi.blog` zone) with `Zone:DNS:Edit`,
18-`Zone:Zone:Read`, and `Account:Cloudflare Pages:Edit`, then:
18+`Zone:Zone:Read`, `Zone:Dynamic Redirect:Edit`, and
19+`Account:Cloudflare Pages:Edit`, then:
1920
2021 ```sh
2122 export CLOUDFLARE_API_TOKEN=...
@@ -15,7 +15,8 @@ on.
15 15
16 Create a token at https://dash.cloudflare.com/profile/api-tokens (Custom16 Create a token at https://dash.cloudflare.com/profile/api-tokens (Custom
17 Token, scoped to the `mykiwi.blog` zone) with `Zone:DNS:Edit`,17 Token, scoped to the `mykiwi.blog` zone) with `Zone:DNS:Edit`,
18-`Zone:Zone:Read`, and `Account:Cloudflare Pages:Edit`, then:18+`Zone:Zone:Read`, `Zone:Dynamic Redirect:Edit`, and
19+`Account:Cloudflare Pages:Edit`, then:
19 20
20 ```sh21 ```sh
21 export CLOUDFLARE_API_TOKEN=...22 export CLOUDFLARE_API_TOKEN=...
modified infra/main.tf +23 -8
@@ -56,15 +56,30 @@ resource "cloudflare_record" "www" {
5656 proxied = true
5757 }
5858
59-resource "cloudflare_page_rule" "www_redirect" {
60- zone_id = data.cloudflare_zone.this.id
61- target = "www.${var.zone_name}/*"
62- priority = 1
59+# Page Rules would also do this but its Edit permission only shows up in
60+# the API token builder for account Super Administrators - Single Redirects
61+# (this resource) works with a normal scoped token (Zone:Dynamic Redirect:Edit).
62+resource "cloudflare_ruleset" "www_redirect" {
63+ zone_id = data.cloudflare_zone.this.id
64+ name = "www to apex redirect"
65+ description = "www.${var.zone_name} -> ${var.zone_name}, path preserved"
66+ kind = "zone"
67+ phase = "http_request_dynamic_redirect"
6368
64- actions {
65- forwarding_url {
66- url = "https://${var.zone_name}/$1"
67- status_code = 301
69+ rules {
70+ ref = "www_redirect"
71+ description = "Redirect www to apex"
72+ expression = "(http.host eq \"www.${var.zone_name}\")"
73+ action = "redirect"
74+
75+ action_parameters {
76+ from_value {
77+ status_code = 301
78+ target_url {
79+ expression = "concat(\"https://${var.zone_name}\", http.request.uri.path)"
80+ }
81+ preserve_query_string = true
82+ }
6883 }
6984 }
7085 }
@@ -56,15 +56,30 @@ resource "cloudflare_record" "www" {
56 proxied = true56 proxied = true
57 }57 }
58 58
59-resource "cloudflare_page_rule" "www_redirect" {59+# Page Rules would also do this but its Edit permission only shows up in
60- zone_id = data.cloudflare_zone.this.id60+# the API token builder for account Super Administrators - Single Redirects
61- target = "www.${var.zone_name}/*"61+# (this resource) works with a normal scoped token (Zone:Dynamic Redirect:Edit).
62- priority = 162+resource "cloudflare_ruleset" "www_redirect" {
63+ zone_id = data.cloudflare_zone.this.id
64+ name = "www to apex redirect"
65+ description = "www.${var.zone_name} -> ${var.zone_name}, path preserved"
66+ kind = "zone"
67+ phase = "http_request_dynamic_redirect"
63 68
64- actions {69+ rules {
65- forwarding_url {70+ ref = "www_redirect"
66- url = "https://${var.zone_name}/$1"71+ description = "Redirect www to apex"
67- status_code = 30172+ expression = "(http.host eq \"www.${var.zone_name}\")"
73+ action = "redirect"
74+
75+ action_parameters {
76+ from_value {
77+ status_code = 301
78+ target_url {
79+ expression = "concat(\"https://${var.zone_name}\", http.request.uri.path)"
80+ }
81+ preserve_query_string = true
82+ }
68 }83 }
69 }84 }
70 }85 }