Terraform-style plan and apply for Cloudflare.
murus plan shows what will change. murus apply
changes it. No state file, no surprises.
Checks the binary against the published SHA256SUMS and
refuses to install on a mismatch.
Read it first, the way you
should with any installer.
$ murus plan admin-api account 00000000 no environment ./wrangler.jsonc settings ~ compatibility_date 2025-01-01 → 2025-11-01 bindings + RATE_LIMITS kv_namespace rate-limits-prod (0000000000000000000000000000aaaa) ~ ADMIN_DB d1 prod-admin (9f3c2211-4d5e-6f70-8192-a3b4c5d6e7f8) → staging-admin (aaaa1111-bbbb-2222-cccc-333344445555) - LEGACY_CACHE kv_namespace old-cache (0000000000000000000000000000cccc) vars - LEGACY_FLAG true ! LEGACY_FLAG is set on the deployed Worker but absent from config, and will be deleted. Add them to `vars`, or set `keep_vars = true` in the config to preserve them. 1 secret set outside config and left untouched. STRIPE_KEY 1 to add, 2 to change, 2 to destroy.
How it works
-
Write the config
Your
wrangler.jsoncis the source of truth. murus reads it. There is nothing else to maintain. -
murus planDiffs the config against the live Worker and prints every add, change, and destroy. The command is read-only. It cannot change anything.
-
murus applyMakes exactly the changes the plan listed, then reads each resource back to confirm it matches. A 200 is not proof. The read-back is.
No state file
Cloudflare already returns a deployed Worker's complete configuration.
So plan is a structural comparison against live
infrastructure. There is no .tfstate to store, share, lock,
or drift, and nothing is deployed into your account to hold state on
your behalf.
$ rm -rf ~/.config/murus murus is gone. There is nothing else to uninstall.
Least privilege, derived
wrangler login asks for 28 OAuth scopes to deploy a Worker
that needs six. Your config already declares every binding, so murus
computes the minimal set and shows you the difference on a credential
you already hold.
| Aspect | wrangler login | murus |
|---|---|---|
| OAuth scopes requested | 28 | 6 |
| Where scopes come from | A fixed set | Derived from your config |
| Permissions you did not ask for | 22 | None |
A status code is not proof
Three of the four Cloudflare create endpoints tested return
200 while silently dropping fields they do not recognise.
So apply reads the resource back afterwards and checks it
against what the plan promised.
$ murus apply applying 1 to add, 2 to change, 2 to destroy + RATE_LIMITS kv_namespace bound to rate-limits-prod ok ~ compatibility_date 2025-01-01 → 2025-11-01 ok - LEGACY_CACHE kv_namespace unbound ok 5 resources read back. All match the plan.
Free for solo work. Team murus is $19 a month, for shared plan history and CI plan checks.