No joke: your git forge in HCL
Terraformer is end of life and archived. Heckle picks up its job for git forges: turning an existing GitHub, GitLab, Gitea or Forgejo namespace into maintainable Terraform or OpenTofu.
Terraformer is gone
For years, Terraformer
from
GoogleCloudPlatform was the go-to tool for "reverse Terraform": pointing it at existing
infrastructure, having it read the live state, and generating .tf files
so you could bring something you had built by hand under Infrastructure as Code.
It covered dozens of providers, and for many it was the pragmatic answer to the
"we already have this thing running, how do we codify it?" question.
Unfortunately, it seems that since March 2026, the repository is now read-only, and states that no further updates, security patches or support will be provided. It's dead, Jim.
Enter Heckle: a focused alternative for git forges
I had a specific scenario that required getting a Github org with many repositories, teams, members, branch protection rules etc into OpenTofu quick smart.
After a few crusty scripts that did the job, I turned my attention to another client's Gitlab.
Then I decided to get my own Forgejo under control, otherwise, whose dog food am I eating in this industry? Not my own!
In the end, I abstracted the logic, made a lot of robustness and provider-specific guardrail fixes, and the result is Heckle .
Heckle inventories a namespace on GitHub, GitLab, Gitea or Forgejo - an organisation,
a GitLab group (including nested subgroups), or a personal account - maps the supported
objects to the selected provider's import contracts, and emits a standalone Terraform or
OpenTofu project of ordinary .tf files and local modules.
Then it steps out of the way: after adoption, Heckle is not required. You just edit and run the generated project like any other Terraform or OpenTofu code.
What makes it safe to adopt
The hard part of reverse Terraform was dealing with provider differences - when I say provider, I mean literally the Terraform/Tofu provider for those forges. Frequently, they seem to work differently to how you use them in the web UI. Either there is contradictory stuff in the APIs, or missing bits, or the developers of the TF providers simply did it a 'different' way, or haven't yet got to adding certain features yet.
In any case, here's some info about Heckle:
- It never runs
apply. Heckle reads your forge, generates HCL, and rehearses the adoption path in disposable local state. It never applies anything, and it never persists that temporary state. - Inspect before you generate.
heckle inventorysaves a discovery snapshot and coverage report without generating any HCL, so you can check what the token can see and what the provider covers before committing to anything.heckle coveragereads a saved report without network access. - Rehearsed adoption. Heckle rehearses the import privately, classifies narrowly-defined, version-scoped known provider behaviour, and stops on anything unrecognised - create, delete, replace or unexpected updates halt generation rather than reaching you as a surprise.
- Guarded by default. Generated resources carry
prevent_destroyguards unless you explicitly opt out, and provider versions are pinned to exact, audited releases (heckle compatibilityshows what this release has audited).
That said, the same caveat Terraformer users knew applies here: Heckle helps you understand a plan; it does not guarantee one is safe. Provider behaviour, forge APIs and upstream bugs can produce unintended changes. Review every plan yourself - the decision to apply, and responsibility for its effects, remains yours. And I'll state it bluntly: Heckle is also currently alpha software. Living on the edge!
Running it
Install with pipx, apt or dnf, or grab an AppImage - see the installation docs . Credentials go through environment variables, never command line options, and are never rendered into provider configuration.
One organisation on GitHub, using the default OpenTofu:
export GITHUB_TOKEN='...'
heckle generate github --org example --out ./github-iac
A nested GitLab group on a self-hosted instance, with Terraform instead of OpenTofu:
export GITLAB_TOKEN='...'
heckle generate gitlab --group example/platform --url https://gitlab.example.org --tf terraform
Personal accounts work across all four forges with the same selectors:
export FORGEJO_API_TOKEN='...'
heckle generate forgejo --me --url https://code.example.org
And the inspect-first workflow, if you want to see coverage before generating anything:
heckle inventory gitea --org example --url https://git.example.org --out ./snapshot
heckle coverage ./snapshot
heckle generate gitea --org example --url https://git.example.org --from-inventory ./snapshot
Out of the project directory, the workflow is the ordinary one:
cd ./github-iac
tofu init
tofu plan -out=import.tfplan
tofu show import.tfplan
# Review every change before running this yourself:
tofu apply import.tfplan
From there, the .tf files and modules are yours to maintain directly, and Heckle is no
longer part of the picture.
Learn more
heckle.tf has the full documentation, provider compatibility details and the adoption flow. As always, the source code is in my Forgejo at git.mig5.net/mig5/heckle .
If you give it a spin on your own forge, let me know how it goes!
- Forges: GitHub, GitLab, Gitea, Forgejo - organisations, groups and personal accounts
- Output: a standalone Terraform or OpenTofu project of
.tffiles and local modules - Workflow:
inventory→coverage→generate→ adopt → maintain without Heckle