Skip to main content
The engine is OpenTofu. These docs already use the tofu-* names everywhere — even where the underlying repos and module sources still carry the legacy terraform-* slug. The documentation rename leads the infrastructure rename on purpose.
This page is the decision record for two questions that come up every time someone opens an IaC repo here: are we on Terraform or OpenTofu? and do we actually need Terragrunt? Short answers: OpenTofu, and only sometimes.

The engine is OpenTofu

Every active IaC repo in the org already runs OpenTofu, not Terraform. This isn’t aspirational — it’s the current state:
  • CI uses opentofu/setup-opentofu and invokes tofu fmt / init / validate / test.
  • Lockfiles pin registry.opentofu.org/* providers, not registry.terraform.io.
  • The Nix dev shell ships both binaries with the intent spelled out in a comment: opentofu # canonical binary, terraform # shipped for compatibility.
  • .envrc files set TERRAGRUNT_TFPATH=tofu / PCT_TFPATH=tofu so every wrapper dispatches to OpenTofu.
For a homelab and personal org, OpenTofu is the no-regrets default and there is no reason to walk it back:
  • Licensing. OpenTofu ships under MPL 2.0 (OSI-approved) under the Linux Foundation. Terraform since 1.6 ships under BSL 1.1, which the OSI does not approve, and is now owned by IBM (the HashiCorp acquisition closed December 2024). None of the cases that justify staying on Terraform — HCP Stacks dependencies, IBM Cloud Pak environments, procurement that mandates HashiCorp as a vendor — apply here. (scalr, oneuptime)
  • Native state encryption. OpenTofu encrypts state (including remote state) natively, without an external KMS workflow.
  • Dynamic config. OpenTofu 1.8+ allows variables and locals inside backend and provider blocks — the single biggest reason teams historically reached for a wrapper. (encore)

The docs use tofu-* ahead of the repos

These docs name the repos tofu-proxmox, tofu-unifi, tofu-aws, and friends. That is the end-state, and the documentation gets there first. The engine inside every one of them is already tofu; the tofu-* display name simply stops pretending otherwise. Newer repos already broke the pattern — .github-tofu uses the tofu-* prefix natively. Convention going forward: new IaC repos use tofu-*. The docs use tofu-* for every IaC repo regardless of whether the underlying git slug has been renamed yet. What the docs do not rewrite is anything load-bearing. The repo links still point at the real URL (github.com/dryvist/terraform-proxmox until that repo is actually renamed — the link text reads tofu-proxmox, the href resolves), and module source references (git::https://github.com/dryvist/terraform-aws-template.git?ref=v0.1.0), CI configuration, the registry.opentofu.org / registry.terraform.io provider URLs, pre-commit hook IDs, and the tf-* AWS role names are untouched. The display name leads; the identifiers follow when the repos are renamed for real. This is deliberate: the docs describe the world we are moving to, and the redirect from the old repo slug holds until the rename lands.

Where Terragrunt earns its place

Terragrunt is used in most repos, but in this environment it is mostly a configuration wrapper, not the multi-module orchestrator it was built to be. It does real work in exactly two repos — tofu-proxmox and tofu-unifi — where it:
  • decrypts SOPS files through the sops_decrypt_file data source,
  • merges a three-layer input model — the deployment.json desired-state fetched fail-loud from S3, SOPS-encrypted config, and Doppler environment variables,
  • resolves IP addressing in locals with cidrhost(),
  • and runs an after_hook that syncs OpenTofu output into the downstream Ansible inventory.
OpenTofu has no native after_hook, and SOPS decryption needs a provider rather than a built-in function. Until those two patterns have a native replacement (a SOPS provider plus a CI step), Terragrunt stays in these two repos. This layered merge is the actual justification for Terragrunt here — not the backend block it also happens to generate.

What we’re phasing out

Everywhere else, Terragrunt only generates a backend and a provider block. OpenTofu 1.8+ does both natively now, and native state encryption removes the KMS rationale — so the wrapper buys nothing. The direction:
RepoEngineTerragrunt todayDirection
tofu-proxmox / tofu-unifitofuSOPS + 3-layer merge + after_hookKeep — earns its place
tofu-github / tofu-runs-on / tofu-aws (basic)tofuBackend + provider generation onlyPhase out → native OpenTofu config
tf-splunk-awstofuMulti-env include (dev/stg/prod)Re-evaluate → native per-env tfvars
.github-tofutofuNoneAlready native — the target shape
We lose nothing we actually use: no repo uses dependency / dependencies cross-module wiring, run-all, stacks, or multi-account fan-out. The orchestration features that justify Terragrunt at scale (terragrunt.com, terramate comparison) simply aren’t in play. The removals themselves are tracked in each affected repo, not here — this page records the why, not the migration steps.

See also

Check placement

Where IaC checks run — static in pre-commit, credentialed in CI via OIDC. Already mandates deleting Terragrunt hooks.

SOPS for IaC

The encrypted-at-rest layer that keeps Terragrunt necessary in the two complex repos.

CI/CD policy

Marketplace actions, release-please, version pinning, plan/apply via OIDC.

Infrastructure overview

The provision-then-configure chain this engine sits at the head of.