# tfenv: a Terraform version manager that keeps version choice in the repository

> tfenv is a shell-based version manager for Terraform, inspired by rbenv. It pins a version per directory through a .terraform-version file, installs releases on demand, and verifies downloads against Hashicorp's published hashes when shasum is on the path.

**tfutils/tfenv** — Terraform version manager

- Repository: https://github.com/tfutils/tfenv
- Stars: 4,973 · Forks: 469
- Language: Shell
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/tfutils-tfenv

## What tfenv solves, and who it is for

Terraform releases move quickly, and a configuration written for one version can fail on another. tfenv gives each project directory its own Terraform binary. You put a version string in a .terraform-version file, and the tfenv shims resolve which binary to run from that file, an environment variable, or a default. The README describes the project as a version manager inspired by rbenv, and the mechanism follows that model closely: small scripts in bin/ that look up a version and then exec the matching Terraform binary.

The audience is teams running Terraform on macOS or Linux, including WSL. If several repositories need different Terraform releases, or if a CI job must install an exact release before a plan, tfenv is aimed at that. It is not a Terraform wrapper that adds plan or apply features, and it does not manage providers.

## How version resolution and installation work

The precedence order is documented in the README. When you run tfenv install with no argument, the version is resolved from the TFENV_TERRAFORM_VERSION environment variable first, then from a .terraform-version file, and the default is latest if neither is present. That order matters: an exported variable overrides the file committed next to the configuration.

Argument forms go beyond plain semver. tfenv install latest takes the newest release, latest:<regex> takes the newest release matching a grep-style regular expression, and two scanning modes read your .tf files. latest-allowed detects the maximally allowed version and min-required detects the minimally required one. The README is explicit that this is not semantic version range parsing. It uses the first version it finds as the candidate, and the user is expected to keep the definition reasonable. The constraint table shows the behaviour per operator: > or >= resolves to the latest available version, <= resolves to that exact version, ~> resolves to the latest matching the prefix, and = or a bare version resolves to that exact version. Only the first constraint before any comma is evaluated.

On the download side, if shasum is on the path tfenv verifies the archive against Hashicorp's published sha256 hash. If keybase is available it also checks the signature using Hashicorp's published public key. GnuPG can be used instead through a use-gpgv file containing trust-tfenv: yes, with the trade-off that the trust-tfenv directive means verification uses a copy of the Hashicorp key shipped in the tfenv repository rather than the system keyring.

## Installing tfenv and pinning a first project

The README lists Homebrew, the Arch User Repository, a Puppet module, and a manual git clone. The clone route works on any supported platform and is the one to read if you want to understand where the files land.

```bash
git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv
```

After cloning, the bin directory has to be on your PATH. The README gives shell-specific lines; for zsh the target file is ~/.zprofile.

```bash
echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.zprofile
```

Once the shims are reachable, install a specific release. The README's example uses 0.7.0, but any semver 2.0.0 string works.

```bash
tfenv install 0.7.0
tfenv use 0.7.0
```

The first command downloads Terraform and stores it under the tfenv install directory. The second writes the version into the resolution state so subsequent terraform calls use it. tfenv list shows installed versions, and tfenv list-remote shows what is available to install.

A common first real use is committing the version next to the configuration. Create a .terraform-version file in the project root, and tfenv install with no argument will read it.

```bash
echo '0.7.0' > .terraform-version
tfenv install
```

You should see tfenv report that it is installing the version written in the file. From then on, anyone in that directory who runs terraform gets that release, provided it is installed or TFENV_AUTO_INSTALL is left at its default of true.

## Where tfenv gets in the way

Windows support is the clearest boundary. The README lists Windows 64-bit as supported only when tested in git-bash, and it requires core.symlinks to be enabled with git config --global core.symlinks true. That is a real constraint rather than a footnote: without symlink support the shim mechanism does not work as intended. Several of the search phrases around this project are about Windows, and the honest answer is that the supported path is git-bash with symlinks turned on, not a native Windows install.

The scanning modes are the second weak spot. min-required and latest-allowed do not parse version ranges. They take the first version they find. A required_version line such as "<0.12.3, >= 0.10.0" will be read as 0.12.3 even though the range has another bound, and the README says it is up to the user to keep the definition reasonable. If your team relies on compound constraints, these two commands will not match your intent.

Finally, tfenv manages Terraform only. It does not install OpenTofu, and it does not manage provider plugins. If your workflows have moved to an OpenTofu fork, tfenv is the wrong tool, and the search phrase tfenv vs tenv points at that fork in the ecosystem.

## tfenv compared with tenv

tenv is the alternative that appears in search queries about this project, and the difference is structural rather than cosmetic. tfenv is a set of shell scripts that resolve a version and exec a Terraform binary; the Dockerfile in the repository shows that shape, installing curl as the only runtime dependency and setting TFENV_ROOT and TFENV_CONFIG_DIR as environment variables.

A tool like tenv is written to manage multiple infrastructure tools from one binary rather than Terraform alone. That matters if your stack also includes OpenTofu or Terragrunt, because a single version manager for all of them avoids running two shim systems side by side. The cost is a larger dependency and a different mental model. tfenv's advantage is that it is small, readable shell, and its resolution rules are documented in one table. If you only need Terraform versions and you already live in a POSIX shell, tfenv's simplicity is the point. If you need one manager across several tools, tfenv will not grow into that role.

## Upgrades, the .terraform-version file, and licence

The README has an Upgrading section, which matters because the manual install is a git clone. Upgrading means pulling the newer tfenv scripts rather than reinstalling Terraform itself; the installed Terraform binaries under the tfenv directory are unaffected by a tfenv upgrade. If you installed through Homebrew, brew handles the script update.

The .terraform-version file is the durable part of a setup. It is a plain text file holding a version string, and the README documents it as one of the two automatic resolution sources. Committing it means the version travels with the configuration, so a new clone resolves to the same release without extra instructions. The environment variable TFENV_TERRAFORM_VERSION overrides it, which is useful in CI but can also surprise someone who expects the file to win.

tfenv is MIT licensed. That permits commercial use and modification, and the repository ships the LICENSE file that the Dockerfile copies to /usr/local/share/licenses/tfenv. This is a description of the licence text, not legal advice; if your organisation has policy about bundled third-party keys or about the trust-tfenv directive, check it against the use-gpgv documentation.

## Deciding whether to run tfenv

tfenv fits teams that already pin Terraform per repository and want the pin to be enforced by the shell rather than by a note in a wiki. The .terraform-version file plus the shim path is a small amount of machinery, and the hash verification against Hashicorp's published sha256 when shasum is present is a concrete reason to prefer it over a hand-rolled download script.

It does not fit Windows-native workflows, teams that depend on compound required_version constraints for automatic selection, or anyone who needs one manager for Terraform and OpenTofu together. The last push to the repository was on 2026-07-01 and the most recent release listed is v3.2.2 from 2026-04-28, so the project is not abandoned, but the README's own notes about first-constraint scanning and git-bash symlinks are the parts to read before you commit to it.

## Conclusion

Adopt tfenv if your projects already carry a .terraform-version file or you need to move between Terraform releases on macOS or Linux without touching global installs. Skip it if you work mainly on Windows outside git-bash, or if you want a single tool that manages both Terraform and OpenTofu, since tfenv only installs Terraform. Before rolling it out, run tfenv list-remote against your pinned constraints and confirm that tfenv install latest-allowed resolves to the version you expect, because the README states that only the first constraint before any comma is evaluated.

## FAQ

### What is tfenv?

tfenv is a Terraform version manager inspired by rbenv. It installs specific Terraform releases and selects which one to run based on an environment variable, a .terraform-version file, or a default of latest.

### How do I install tfenv on Ubuntu?

The README's manual route is to clone the repository and add its bin directory to PATH. On Ubuntu or Debian, touching /usr/local/bin may need sudo, so the README suggests creating ~/.local/bin, sourcing ~/.profile, and symlinking the tfenv bin scripts into it.

### How do I install tfenv on macOS?

The README lists Homebrew as the automatic option with brew install tfenv. The manual alternative is to clone the repository into a path such as ~/.tfenv and add ~/.tfenv/bin to PATH.

### How do I install tfenv on Windows?

Windows 64-bit is listed as supported when tested in git-bash, and the README requires core.symlinks to be enabled with git config --global core.symlinks true. There is no native Windows installation path documented.

### How do I switch between Terraform versions with tfenv?

Install the release you need with tfenv install <version> and then select it with tfenv use <version>. tfenv list shows what is installed, and a .terraform-version file makes the choice automatic for a directory.

### How do I use tfenv with Terraform?

tfenv provides shims that resolve a version and then run the matching Terraform binary. The README documents tfenv install, tfenv use, tfenv list, tfenv list-remote, and tfenv pin as the main commands, with TFENV_AUTO_INSTALL controlling whether a missing version is fetched automatically.

## Sources

- [Issues](https://github.com/tfutils/tfenv/issues)
- [License: MIT](https://github.com/tfutils/tfenv/blob/master/LICENSE)
- [README](https://github.com/tfutils/tfenv/blob/master/README.md)
- [Releases](https://github.com/tfutils/tfenv/releases)
- [tfutils/tfenv on GitHub](https://github.com/tfutils/tfenv)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tfutils-tfenv
