Skip to content

feat: scaffold terraform layout, CI, and perish.dev zone import - #2

Merged
hasansezertasan merged 8 commits into
mainfrom
feat/terraform-skeleton
Jun 25, 2026
Merged

hasansezertasan merged 8 commits into
mainfrom
feat/terraform-skeleton

Conversation

@hasansezertasan

Copy link
Copy Markdown
Member

Summary

Implements the contracts merged in #1.

  • `terraform/cloudflare/` — single HCP workspace (`cloudflare`), v5 provider, locals for domain/account/zone IDs, `import` block + `cloudflare_zone` resource for `perish.dev`. Local `terraform plan` against HCP shows clean import (`1 to import, 0 to add, 0 to change, 0 to destroy`).
  • `terraform/github/` — single workspace (`github-org`), v6 provider with GitHub App auth, no resources yet.
  • `Makefile` — `fmt` / `fmt-check` / `init` / `validate` / `plan` targets that fan out across every leaf with a `versions.tf`.
  • `.github/workflows/ci.yml` — fork-safe `terraform fmt` and `terraform validate` gates. No secrets. Real plans run via HCP's VCS integration.
  • `docs/setup.md` — runbook for the out-of-band HCP + Cloudflare token + GitHub App setup that has to happen before the code runs.
  • `docs/import.md` — `cf-terraforming` runbook for importing existing Cloudflare resources (DNS, R2, Pages) — replaces an earlier hand-rolled discovery script.

Branched off #1 and stacked on it. Merge #1 first.

Test plan

  • `terraform init` succeeds locally against HCP workspace `cloudflare`.
  • `terraform plan` shows `1 to import, 0 to add, 0 to change, 0 to destroy`.
  • HCP speculative plan on this PR matches the local plan.
  • After merge: confirm apply in HCP UI for the `cloudflare` workspace.
  • After merge: `terraform plan` in the `github-org` workspace returns `No changes` (proves App auth works without changing anything).

Per the design in docs/secrets.md, docs/state.md, and docs/ci.md, lay
down the directory shape the first real resources will fill:

- terraform/cloudflare/ — single HCP workspace (we manage one apex
  domain in one Cloudflare account, so per-env split is premature).
  Declares the cloud {} block and cloudflare/cloudflare v5 provider
  with sensitive variables HCP supplies at run time.
- terraform/github/ — single workspace for the org; uses the
  integrations/github v6 provider with GitHub App auth.
- Makefile — fmt / fmt-check / init / validate / plan targets that
  fan out across every leaf with a versions.tf.
- terraform/README.md — explains the workspace-per-leaf convention,
  why there is no per-environment split yet, and the procedure for
  adding new workspaces.

No real resources yet. terraform validate should pass once HCP
workspaces are created and tokens are wired up.
GitHub Actions workflow that runs on every PR (including from forks)
and on pushes to main:

- fmt job: terraform fmt -check -recursive across terraform/.
- validate job: matrix over each leaf dir, runs terraform init with
  -backend=false (no HCP auth, no state access) then terraform validate.

No secrets are referenced. Real plans and applies run in HCP Terraform
via its VCS integration, not from this workflow — keeping the trust
boundary clean per docs/ci.md.
- terraform/cloudflare/main.tf: add locals for domain, account_id, and
  zone_id (non-credentials, safe to commit per docs/secrets.md), an
  import block for the existing zone, and the cloudflare_zone resource
  it imports into.
- terraform/cloudflare/variables.tf: drop cloudflare_account_id var;
  the value lives in locals now.
- scripts/cf_discover.py: uv-runnable Python script that lists DNS
  records, Workers scripts and routes, R2 buckets, and Pages projects
  via the Cloudflare API and emits matching import blocks + resource
  stubs to terraform/cloudflare/generated.tf. Re-runnable; commit its
  output and review the diff.

Code is speculative until HCP Terraform is set up — see docs/setup.md
(added in a follow-up commit).
Step-by-step out-of-band setup that has to happen before any of the
Terraform code in this repo can actually run: HCP org/workspaces,
Cloudflare API token with the scopes cf_discover.py needs, GitHub App
creation and installation, local terraform login, and finally the
cf_discover import flow.
The hand-rolled discovery script duplicated Cloudflare's own
cf-terraforming CLI without matching its coverage or upkeep. Delete it
and document cf-terraforming instead:

- docs/import.md: runbook for cf-terraforming v0.27 — install, generate
  HCL, emit modern import blocks, verify the plan. Lists what's
  supported in the v5 provider (DNS records, R2 buckets, Pages
  projects, KV namespaces) and what's intentionally out of scope
  (Workers script content — lives in the app repo, not here).
- docs/setup.md: step 7 now points at import.md instead of the script.
- terraform/cloudflare/main.tf: comment references cf-terraforming
  instead of the deleted script.

Saves us from maintaining a parallel import tool that would lag every
provider release.
Base automatically changed from feat/useful-gull to main June 25, 2026 13:04
@hasansezertasan
hasansezertasan merged commit d68a778 into main Jun 25, 2026
4 checks passed
@hasansezertasan
hasansezertasan deleted the feat/terraform-skeleton branch June 25, 2026 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant