From 4bc6ce1aca3da510ae227b51017bfd41f18c2936 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 30 Sep 2026 01:31:22 +0000 Subject: [PATCH 1/2] fix(infra): create the demo Workers through the scripts API cloudflare_worker's create call returns 403 for this token even with Workers Scripts Write and Workers Editor. The router already works through cloudflare_workers_script, so create each demo Worker the same way with a placeholder, and ignore later changes because the Deploy Examples workflow owns the code. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NUEPGc2SgMUHxx4Z28HS8v --- infra/main.tf | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/infra/main.tf b/infra/main.tf index 7fd80c4..9f758e7 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -152,16 +152,27 @@ locals { ) } -resource "cloudflare_worker" "demo" { - for_each = local.demo_workers - account_id = var.account_id - name = each.value - - # Only reachable through the routes below, like workers_dev = false and - # preview_urls = false in each wrangler.toml. - subdomain = { - enabled = false - previews_enabled = false +# Created through the scripts API, like the router, with a placeholder that +# answers 503 until the Deploy Examples workflow uploads the real code. After +# that the workflow owns the code and settings, so Terraform never updates +# them. (cloudflare_worker's newer Workers API returned 403 for this token even +# with Workers Scripts Write and Workers Editor.) +resource "cloudflare_workers_script" "demo" { + for_each = local.demo_workers + account_id = var.account_id + script_name = each.value + main_module = "placeholder.js" + compatibility_date = "2026-09-01" + content = <<-JS + export default { + fetch() { + return new Response("This demo hasn't been deployed yet.", { status: 503 }); + }, + }; + JS + + lifecycle { + ignore_changes = all } } @@ -171,7 +182,7 @@ resource "cloudflare_workers_route" "demo" { for_each = local.demo_routes zone_id = var.zone_id pattern = each.value.pattern - script = cloudflare_worker.demo[each.value.worker].name + script = cloudflare_workers_script.demo[each.value.worker].script_name } # --- VS Code Marketplace Domain Verification --- From 49f77891dff350c0047481ce8206a30ecbc422a3 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 30 Sep 2026 01:32:28 +0000 Subject: [PATCH 2/2] fix(infra): keep the Workers the first apply created Routes can't point at a code-less cloudflare_worker, which is why the second apply failed after creating them. Forget those resources with a removed block instead of destroying them, and let the placeholder scripts upload to the same names. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NUEPGc2SgMUHxx4Z28HS8v --- infra/main.tf | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/infra/main.tf b/infra/main.tf index 9f758e7..eec7461 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -155,8 +155,9 @@ locals { # Created through the scripts API, like the router, with a placeholder that # answers 503 until the Deploy Examples workflow uploads the real code. After # that the workflow owns the code and settings, so Terraform never updates -# them. (cloudflare_worker's newer Workers API returned 403 for this token even -# with Workers Scripts Write and Workers Editor.) +# them. A code-less cloudflare_worker can't take routes ("Cannot configure a +# route for a Worker which does not exist"), so the placeholder is what lets +# the routes apply before the first deploy. resource "cloudflare_workers_script" "demo" { for_each = local.demo_workers account_id = var.account_id @@ -176,6 +177,16 @@ resource "cloudflare_workers_script" "demo" { } } +# The first apply created these as code-less cloudflare_worker resources. +# Forget them without deleting; the scripts above upload to the same names. +removed { + from = cloudflare_worker.demo + + lifecycle { + destroy = false + } +} + # Cloudflare sends a request to the most specific matching route, so the # example routes win over the landing page's catch-all. resource "cloudflare_workers_route" "demo" {