tenv

Github release Contributors maintenance status Go report codecov


Logo

tenv

OpenTofu, Terraform and Terragrunt version manager, written in Go.
· Report Bug · Request Feature

About The Project

Welcome to tenv, a versatile version manager for OpenTofu, Terraform and Terragrunt, written in Go. Our tool simplifies the complexity of handling different versions of these powerful tools, ensuring developers and DevOps professionals can focus on what matters most - building and deploying efficiently.

tenv is a successor of tofuenv and tfenv.

Key Features

Difference with asdf

asdf share the same goals than tenv : simplify the usage of several version of tools.

asdf is generic and extensible with a plugin system, key tenv differences :

Table of Contents

Table of Contents
  1. About The Project
  2. Table of contents
  3. Getting Started
  4. Usage
  5. Environment variables
  6. Version files
  7. Technical details
  8. Contributing
  9. Community
  10. Authors
  11. Licence

Getting Started

Prerequisites

If you need to enable cosign checks, install cosign tool via one of the following commands:

MacOS (Homebrew)
```sh brew install cosign ```
Windows (Chocolatey)
```sh choco install cosign ```
Alpine Linux
```sh apk add cosign ```
Arch Linux
```sh sudo pacman -S cosign ```
Linux: RPM
```sh LATEST_VERSION=$(curl https://api.github.com/repos/sigstore/cosign/releases/latest | jq -r .tag_name | tr -d "v") curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign-${LATEST_VERSION}-1.x86_64.rpm" sudo rpm -ivh cosign-${LATEST_VERSION}.x86_64.rpm ```
Linux: dkpg
```sh LATEST_VERSION=$(curl https://api.github.com/repos/sigstore/cosign/releases/latest | jq -r .tag_name | tr -d "v") curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign_${LATEST_VERSION}_amd64.deb" sudo dpkg -i cosign_${LATEST_VERSION}_amd64.deb ```

Installation

Automatic Installation

Arch Linux (AUR)
This package is available on the Arch Linux User Repository. It can be installed using the yay AUR helper: ```sh yay tenv-bin ```
MacOS (Homebrew)
```console brew tap tofuutils/tap brew install tenv ```
Windows (Chocolatey)
```console choco install tenv ```
Ubuntu
```sh LATEST_VERSION=$(curl --silent https://api.github.com/repos/tofuutils/tenv/releases/latest | jq -r .tag_name) curl -O -L "https://github.com/tofuutils/tenv/releases/latest/download/tenv_${LATEST_VERSION}_amd64.deb" sudo dpkg -i "tenv_${LATEST_VERSION}_amd64.deb" ```

Manual Installation

Get the most recent packaged binaries (.deb, .rpm, .apk, pkg.tar.zst , .zip or .tar.gz format) by visiting the release page. After downloading, unzip the folder and seamlessly integrate it into your system’s PATH.

Docker Installation

You can use dockerized version of tenv via the following command:

docker run --rm --it ghcr.io/tofuutils/tenv:latest help

The docker container is not meant as a way to run tenv for CI pipelines, for local use, you should use one of the packaged binaries.

Usage

tenv supports OpenTofu, Terragrunt and Terraform. To manage each binary you can use tenv <tool> <command>. Below is a list of tools and commands that use actual subcommands:

tool (alias) env vars description
tofu (opentofu) TOFUENV_ OpenTofu
tf (terraform) TFENV_ Terraform
tg (terragrunt) TG_ Terragrunt
tenv <tool> install [version]
Install a requested version of the tool (into `TENV_ROOT` directory from `_REMOTE` url). Without a parameter, the version to use is resolved automatically (see resolution order in [tools description](#technical-details), with `latest` as default in place of `latest-allowed`). If a parameter is passed, available options include: - an exact [Semver 2.0.0](https://semver.org/) version string to install. - a [version constraint](https://opentofu.org/docs/language/expressions/version-constraints) string (checked against versions available at `_REMOTE` url). - `latest`, `latest-stable` (old name of `latest`) or `latest-pre` (include unstable version), which are checked against versions available at `_REMOTE` url. - `latest:` or `min:` to get first version matching with `` as a [regexp](https://github.com/google/re2/wiki/Syntax) after a descending or ascending version sort. - `latest-allowed` or `min-required` to scan your IAC files to detect which version is maximally allowed or minimally required. See [required_version](#required_version) docs. ```console tenv tofu install tenv tofu install 1.6.0-beta5 tenv tf install "~> 1.6.0" tenv tf install latest-pre tenv tg install latest tenv tg install latest-stable tenv install latest-allowed tenv install min-required ``` A complete display : ```console $ tenv tofu install 1.6.0 Installing OpenTofu 1.6.0 Fetching release information from https://api.github.com/repos/opentofu/opentofu/releases/tags/v1.6.0 Downloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_linux_amd64.zip Downloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS Downloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS.sig Downloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS.pem Installation of OpenTofu 1.6.0 successful ``` </details>
tenv <tool> use [version]
Switch the default tool version to use (set in `TENV_ROOT//version` file). `tenv use` has a `--working-dir`, `-w` flag to write a [version file](#version-files) in working directory. Available parameter options: - an exact [Semver 2.0.0](https://semver.org/) version string to use. - a [version constraint](https://opentofu.org/docs/language/expressions/version-constraints) string (checked against versions available in TENV_ROOT directory). - `latest`, `latest-stable` (old name of `latest`) or `latest-pre` (include unstable version), which are checked against versions available in TENV_ROOT directory. - `latest:` or `min:` to get first version matching with `` as a [regexp](https://github.com/google/re2/wiki/Syntax) after a descending or ascending version sort. - `latest-allowed` or `min-required` to scan your IAC files to detect which version is maximally allowed or minimally required. See [required_version](#required_version) docs. ```console tenv tofu use v1.6.0-beta5 tenv tf use min-required tenv tg use latest tenv tofu use latest-allowed ``` </details>
tenv <tool> detect
Detect the used version of tool for the working directory. ```console $ tenv tofu detect No version files found for OpenTofu, fallback to latest-allowed strategy Scan project to find .tf files No OpenTofu version requirement found in project files, fallback to latest strategy Found compatible version installed locally : 1.6.1 OpenTofu 1.6.1 will be run from this directory. $ tenv tg detect -q Terragrunt 0.55.1 will be run from this directory. ```
tenv <tool> reset
Reset used version of tool (remove `TENV_ROOT//version` file). ```console $ tenv tofu reset Removed /home/dvaumoron/.tenv/OpenTofu/version ``` </details>
tenv <tool> uninstall [version]
Uninstall a specific version of the tool (remove it from `TENV_ROOT` directory without interpretation). ```console $ tenv tofu uninstall v1.6.0-alpha4 Uninstallation of OpenTofu 1.6.0-alpha4 successful (directory /home/dvaumoron/.tenv/OpenTofu/1.6.0-alpha4 removed) ```
tenv <tool> list
List installed tool versions (located in `TENV_ROOT` directory), sorted in ascending version order. `tenv list` has a `--descending`, `-d` flag to sort in descending order. ```console $ tenv tofu list -v * 1.6.0 (set by /home/dvaumoron/.tenv/OpenTofu/version) 1.6.1 found 2 OpenTofu version(s) managed by tenv. ``` </details>
tenv <tool> list-remote
List installable tool versions (from `_REMOTE` url), sorted in ascending version order. `tenv list-remote` has a `--descending`, `-d` flag to sort in descending order. `tenv list-remote` has a `--stable`, `-s` flag to display only stable version. ```console $ tenv tofu list-remote Fetching all releases information from https://api.github.com/repos/opentofu/opentofu/releases 1.6.0-alpha1 1.6.0-alpha2 1.6.0-alpha3 1.6.0-alpha4 1.6.0-alpha5 1.6.0-beta1 1.6.0-beta2 1.6.0-beta3 1.6.0-beta4 1.6.0-beta5 1.6.0-rc1 1.6.0 (installed) 1.6.1 (installed) ``` </details>
tenv <tool> constraint [expression]
Set or reset a default constraint expression for the tool. ```console $ tenv tf constraint "<= 1.5.7" Written <= 1.5.7 in /home/dvaumoron/.tenv/Terraform/constraint ``` Or without expression : ```console $ tenv tg constraint Removed /home/dvaumoron/.tenv/Terragrunt/constraint ```
tenv help [command]
Help about any command. You can use `--help` `-h` flag instead. ```console $ tenv help tf detect Display Terraform current version. Usage: tenv tf detect [flags] Flags: -a, --arch string specify arch for binaries downloading (default "amd64") -f, --force-remote force search on versions available at TFENV_REMOTE url -h, --help help for detect -k, --key-file string local path to PGP public key file (replace check against remote one) -n, --no-install disable installation of missing version -c, --remote-conf string path to remote configuration file (advanced settings) -u, --remote-url string remote url to install from Global Flags: -q, --quiet no unnecessary output (and no log) -r, --root-path string local path to install versions of OpenTofu, Terraform and Terragrunt (default "/home/dvaumoron/.tenv") -v, --verbose verbose output (and set log level to Trace) ``` ```console $ tenv tofu use -h Switch the default OpenTofu version to use (set in TENV_ROOT/OpenTofu/version file) Available parameter options: - an exact Semver 2.0.0 version string to use - a version constraint expression (checked against version available in TENV_ROOT directory) - latest, latest-stable or latest-pre (checked against version available in TENV_ROOT directory) - latest-allowed or min-required to scan your OpenTofu files to detect which version is maximally allowed or minimally required. Usage: tenv tofu use version [flags] Flags: -a, --arch string specify arch for binaries downloading (default "amd64") -f, --force-remote force search on versions available at TOFUENV_REMOTE url -t, --github-token string GitHub token (increases GitHub REST API rate limits) -h, --help help for use -k, --key-file string local path to PGP public key file (replace check against remote one) -n, --no-install disable installation of missing version -c, --remote-conf string path to remote configuration file (advanced settings) -u, --remote-url string remote url to install from -w, --working-dir create .opentofu-version file in working directory Global Flags: -q, --quiet no unnecessary output (and no log) -r, --root-path string local path to install versions of OpenTofu, Terraform and Terragrunt (default "/home/dvaumoron/.tenv") -v, --verbose verbose output (and set log level to Trace) ```
tenv update-path
Display PATH updated with tenv directory location first. With GITHUB_ACTIONS set to true, write tenv directory location to GITHUB_PATH. This command can be used when one of the managed tool is already installed on your system and hide the corresponding proxy (in that case `which tenv` and `which ` will indicate different locations). The following shell call should resolve such issues : ```console export PATH=$(tenv update-path) ``` </details>
tenv version
Display tenv current version. ```console $ tenv version tenv version v1.7.0 ```
## Environment variables **tenv** commands support global environment variables and variables by tool for : [OpenTofu](https://opentofu.org), [Terraform](https://www.terraform.io/) and [TerraGrunt](https://terragrunt.gruntwork.io/). ### Global tenv environment variables
TENV_ARCH
String (Default: current tenv binaries architecture) Allow to override the default architecture for binaries downloading during installation. `tenv ` subcommands `detect`, `install` and `use` support a `--arch`, `-a` flag version. </details>
TENV_AUTO_INSTALL
String (Default: true) If set to true **tenv** will automatically install missing tool versions needed. `tenv ` subcommands `detect` and `use` support a `--no-install`, `-n` disabling flag version. </details>
TENV_FORCE_REMOTE
String (Default: false) If set to true **tenv** detection of needed version will skip local check and verify compatibility on remote list. `tenv ` subcommands `detect` and `use` support a `--force-remote`, `-f` flag version. </details>
TENV_GITHUB_TOKEN
String (Default: "") Allow to specify a GitHub token to increase [GitHub Rate limits for the REST API](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api). Useful because OpenTofu and Terragrunt binaries are downloaded from GitHub repository. `tenv tofu` and `tenv tg` subcommands `detect`, `install`, `list-remote` and `use` support a `--github-token`, `-t` flag version.
TENV_QUIET
String (Default: false) If set to true **tenv** disable unnecessary output (including log level forced to off). `tenv` subcommands support a `--quiet`, `-q` flag version.
TENV_LOG
String (Default: "warn") Set **tenv** log level (possibilities sorted by decreasing verbosity : "trace", "debug", "info", "warn", "error", "off"). `tenv` support a `--verbose`, `-v` flag which set log level to "trace".
TENV_REMOTE_CONF
String (Default: `${TENV_ROOT}/remote.yaml`) The path to a yaml file for [advanced remote configuration](#advanced-remote-configuration) (can be used to call artifact mirror). `tenv ` subcommands `detect`, `install`, `list-remote` and `use` support a `--remote-conf`, `-c` flag version. </details>
TENV_ROOT
String (Default: `${HOME}/.tenv`) The path to a directory where the local OpenTofu versions, Terraform versions, Terragrunt versions and tenv configuration files exist. `tenv` support a `--root-path`, `-r` flag version.
GITHUB_ACTIONS
String (Default: false) If set to true **tenv** proxies exposes proxied output `stdout`, `stderr`, and `exitcode` by writing them into GITHUB_OUTPUT in [multiline format](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings). GitHub Actions set it (see [default environment variables](https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables)).
GITHUB_OUTPUT
String (Default: "") Needed when GITHUB_ACTIONS is set to true, path to a file to write proxied output.
GITHUB_PATH
String (Default: "") Used by `tenv update-path` when GITHUB_ACTIONS is set to true, path to a file to write tenv directory location.
### OpenTofu environment variables
TOFUENV_ARCH
Same as TENV_ARCH (compatibility with [tofuenv](https://github.com/tofuutils/tofuenv)).
TOFUENV_AUTO_INSTALL
Same as TENV_AUTO_INSTALL (compatibility with [tofuenv](https://github.com/tofuutils/tofuenv)). #### Example 1 Use OpenTofu version 1.6.1 that is not installed, and auto installation is disabled : ```console $ TOFUENV_AUTO_INSTALL=false tenv use 1.6.1 Written 1.6.1 in /home/dvaumoron/.tenv/OpenTofu/version ``` #### Example 2 Use OpenTofu version 1.6.0 that is not installed, and auto installation stay enabled : ```console $ tenv tofu use 1.6.0 Installing OpenTofu 1.6.0 Fetching release information from https://api.github.com/repos/opentofu/opentofu/releases/tags/v1.6.0 Downloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_linux_amd64.zip Downloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS Downloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS.sig Downloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS.pem Installation of OpenTofu 1.6.0 successful Written 1.6.0 in /home/dvaumoron/.tenv/OpenTofu/version ```
TOFUENV_FORCE_REMOTE
Same as TENV_FORCE_REMOTE.
TOFUENV_INSTALL_MODE
String (Default: "api") - "api" install mode retrieve download url of OpenTofu from [Github REST API](https://docs.github.com/en/rest?apiVersion=2022-11-28) (TOFUENV_REMOTE must comply with it). - "direct" install mode generate download url of OpenTofu based on TOFUENV_REMOTE. See [advanced remote configuration](#advanced-remote-configuration) for more details.
TOFUENV_LIST_MODE
String (Default: "api") - "api" list mode retrieve information of OpenTofu releases from [Github REST API](https://docs.github.com/en/rest?apiVersion=2022-11-28) (TOFUENV_LIST_URL must comply with it). - "html" list mode extract information of OpenTofu releases from parsing an html page in TOFUENV_LIST_URL. See [advanced remote configuration](#advanced-remote-configuration) for more details.
TOFUENV_LIST_URL
String (Default: "") Allow to override the remote url only for the releases listing, default value depend on TOFUENV_LIST_MODE : - with "api" mode use default API URL (https://api.github.com/repos/opentofu/opentofu/releases) - with "html" mode same as TOFUENV_REMOTE See [advanced remote configuration](#advanced-remote-configuration) for more details.
TOFUENV_OPENTOFU_PGP_KEY
String (Default: "") Allow to specify a local file path to OpenTofu PGP public key, if not present download https://get.opentofu.org/opentofu.asc. `tenv tofu` subcommands `detect`, `ìnstall` and `use` support a `--key-file`, `-k` flag version.
TOFUENV_REMOTE
String (Default: https://api.github.com/repos/opentofu/opentofu/releases) URL to install OpenTofu, when TOFUENV_REMOTE differ from its default value, TOFUENV_INSTALL_MODE is set to direct (assume an artifact proxy usage, however releases listing continue to use API). `tenv tofu` subcommands `detect`, `install`, `list-remote` and `use` support a `--remote-url`, `-u` flag version. See [advanced remote configuration](#advanced-remote-configuration) for more details.
TOFUENV_ROOT
Same as TENV_ROOT (compatibility with [tofuenv](https://github.com/tofuutils/tofuenv)).
TOFUENV_GITHUB_TOKEN
Same as TENV_GITHUB_TOKEN (compatibility with [tofuenv](https://github.com/tofuutils/tofuenv)).
TOFUENV_TOFU_DEFAULT_CONSTRAINT
String (Default: "") If not empty string, this variable overrides OpenTofu default constraint, specified in ${TENV_ROOT}/OpenTofu/constraint file.
TOFUENV_TOFU_DEFAULT_VERSION
String (Default: "") If not empty string, this variable overrides OpenTofu fallback version, specified in ${TENV_ROOT}/OpenTofu/version file.
TOFUENV_TOFU_VERSION
String (Default: "") If not empty string, this variable overrides OpenTofu version, specified in [`.opentofu-version`](#opentofu-version-files) files. `tenv tofu` subcommands `install` and `detect` also respects this variable. e.g. with : ```console $ tofu version OpenTofu v1.6.1 on linux_amd64 ``` then : ```console $ TOFUENV_TOFU_VERSION=1.6.0 tofu version OpenTofu v1.6.0 on linux_amd64 ```
### Terraform environment variables
TFENV_ARCH
Same as TENV_ARCH (compatibility with [tfenv](https://github.com/tfutils/tfenv)).
TFENV_AUTO_INSTALL
Same as TENV_AUTO_INSTALL (compatibility with [tfenv](https://github.com/tfutils/tfenv)).
TFENV_FORCE_REMOTE
Same as TENV_FORCE_REMOTE.
TFENV_HASHICORP_PGP_KEY
String (Default: "") Allow to specify a local file path to Hashicorp PGP public key, if not present download https://www.hashicorp.com/.well-known/pgp-key.txt. `tenv tf` subcommands `detect`, `ìnstall` and `use` support a `--key-file`, `-k` flag version.
TFENV_INSTALL_MODE
String (Default: "api") - "api" install mode retrieve download url of Terraform from [Hashicorp Release API](https://releases.hashicorp.com/docs/api/v1) (TFENV_REMOTE must comply with it). - "direct" install mode generate download url of Terraform based on TFENV_REMOTE. See [advanced remote configuration](#advanced-remote-configuration) for more details.
TFENV_LIST_MODE
String (Default: "api") - "api" list mode retrieve information of Terraform releases from [Hashicorp Release API](https://releases.hashicorp.com/docs/api/v1) (TFENV_LIST_URL must comply with it). - "html" list mode extract information of Terraform releases from parsing an html page in TFENV_LIST_URL. See [advanced remote configuration](#advanced-remote-configuration) for more details.
TFENV_LIST_URL
String (Default: "") Allow to override the remote url only for the releases listing, default value depend on TFENV_LIST_MODE : - with "api" mode use default API URL (https://releases.hashicorp.com) - with "html" mode same as TFENV_REMOTE See [advanced remote configuration](#advanced-remote-configuration) for more details.
TFENV_REMOTE
String (Default: https://releases.hashicorp.com) URL to install Terraform (can differ from its default, an artifact proxy will not disturb the retrieving of release index.json, however releases listing continue to use API). `tenv tf` subcommands `detect`, `install`, `list-remote` and `use` support a `--remote-url`, `-u` flag version. See [advanced remote configuration](#advanced-remote-configuration) for more details.
TFENV_ROOT
Same as TENV_ROOT (compatibility with [tfenv](https://github.com/tfutils/tfenv)).
TFENV_TERRAFORM_DEFAULT_CONSTRAINT
String (Default: "") If not empty string, this variable overrides Terraform default constraint, specified in ${TENV_ROOT}/Terraform/constraint file.
TFENV_TERRAFORM_DEFAULT_VERSION
String (Default: "") If not empty string, this variable overrides Terraform fallback version, specified in ${TENV_ROOT}/Terraform/version file.
TFENV_TERRAFORM_VERSION
String (Default: "") If not empty string, this variable overrides Terraform version, specified in [`.terraform-version`](#terraform-version-files) files. `tenv tf` subcommands `install` and `detect` also respects this variable. e.g. with : ```console $ terraform version Terraform v1.7.2 on linux_amd64 ``` then : ```console $ TFENV_TERRAFORM_VERSION=1.7.0 terraform version Terraform v1.7.0 on linux_amd64 Your version of Terraform is out of date! The latest version is 1.7.2. You can update by downloading from https://www.terraform.io/downloads.html ```
### Terragrunt environment variables
TG_INSTALL_MODE
String (Default: "api") - "api" install mode retrieve download url of Terragrunt from [Github REST API](https://docs.github.com/en/rest?apiVersion=2022-11-28) (TG_REMOTE must comply with it). - "direct" install mode generate download url of Terragrunt based on TG_REMOTE. See [advanced remote configuration](#advanced-remote-configuration) for more details.
TG_LIST_MODE
String (Default: "api") - "api" list mode retrieve information of Terragrunt releases from [Github REST API](https://docs.github.com/en/rest?apiVersion=2022-11-28) (TG_LIST_URL must comply with it). - "html" list mode extract information of Terragrunt releases from parsing an html page in TG_LIST_URL. See [advanced remote configuration](#advanced-remote-configuration) for more details.
TG_LIST_URL
String (Default: "") Allow to override the remote url only for the releases listing, default value depend on TG_LIST_MODE : - with "api" mode use default API URL (https://api.github.com/repos/gruntwork-io/terragrunt/releases) - with "html" mode same as TG_REMOTE See [advanced remote configuration](#advanced-remote-configuration) for more details.
TG_REMOTE
String (Default: https://api.github.com/repos/gruntwork-io/terragrunt/releases) URL to install Terragrunt, when TG_REMOTE differ from its default value, TG_INSTALL_MODE is set to "direct" (assume an artifact proxy usage, however releases listing continue to use API). `tenv tg` subcommands `detect`, `install`, `list-remote` and `use` support a `--remote-url`, `-u` flag version. See [advanced remote configuration](#advanced-remote-configuration) for more details.
TG_DEFAULT_CONSTRAINT
String (Default: "") If not empty string, this variable overrides Terragrunt default constraint, specified in ${TENV_ROOT}/Terragrunt/constraint file.
TG_DEFAULT_VERSION
String (Default: "") If not empty string, this variable overrides Terragrunt fallback version, specified in ${TENV_ROOT}/Terragrunt/version file.
TG_VERSION
String (Default: "") If not empty string, this variable overrides Terragrunt version, specified in [`.terragrunt-version`](#terragrunt-version-files) files. `tenv tg` subcommands `install` and `detect` also respects this variable. e.g. with : ```console $ terragrunt -v terragrunt version v0.55.1 ``` then : ```console $ TG_VERSION=0.54.1 terragrunt -v terragrunt version v0.54.1 ```
## version files
default version file
The `TENV_ROOT//version` file is the tool default version used when no project specific or user specific are found. It can be written with `tenv use`. </details>
opentofu version files
If you put a `.opentofu-version` file in the working directory, one of its parent directory, or user home directory, **tenv** detects it and uses the version written in it. Note, that TOFUENV_TOFU_VERSION can be used to override version specified by `.opentofu-version` file. Recognize same values as `tenv tofu use` command. See [required_version](https://opentofu.org/docs/language/settings#specifying-a-required-opentofu-version) docs.
terraform version files
If you put a `.terraform-version` or `.tfswitchrc` file in the working directory, one of its parent directory, or user home directory, **tenv** detects it and uses the version written in it. Note, that TFENV_TERRAFORM_VERSION can be used to override version specified by those files. Recognize same values as `tenv tf use` command. See [required_version](https://developer.hashicorp.com/terraform/language/settings#specifying-a-required-terraform-version) docs.
terragrunt version files
If you put a `.terragrunt-version` or a `.tgswitchrc` file in the working directory, one of its parent directory, or user home directory, **tenv** detects it and uses the version written in it. **tenv** also detect a `version` field in a `.tgswitch.toml` in same places. Note, that TG_VERSION can be used to override version specified by those files. Recognize same values as `tenv tg use` command.
terragrunt.hcl file
If you have a terragrunt.hcl or terragrunt.hcl.json in the working directory, one of its parent directory, or user home directory, **tenv** will read constraint from `terraform_version_constraint` or `terragrunt_version_constraint` field in it (depending on proxy or subcommand used).
required_version
the `latest-allowed` or `min-required` strategies scan through your IAC files (.tf or .tf.json) and identify a version conforming to the constraint in the relevant files. They fallback to `latest` when no IAC files and no default constraint are found. Currently the format for [Terraform required_version](https://developer.hashicorp.com/terraform/language/settings#specifying-a-required-terraform-version) and [OpenTofu required_version](https://opentofu.org/docs/language/settings#specifying-a-required-opentofu-version) are very similar, however this may change over time, always refer to docs for the latest format specification. example: ```HCL version = ">= 1.2.0, < 2.0.0" ``` This would identify the latest version at or above 1.2.0 and below 2.0.0
## Technical details ### Project binaries
tofu
The `tofu` command in this project is a proxy to OpenTofu's `tofu` command managed by **tenv**. The version resolution order is : - TOFUENV_TOFU_VERSION environment variable - `.opentofu-version` file - `terraform_version_constraint` from `terragrunt.hcl` file - `terraform_version_constraint` from `terragrunt.hcl.json` file - TOFUENV_TOFU_DEFAULT_VERSION environment variable - `${TENV_ROOT}/OpenTofu/version` file (can be written with `tenv tofu use`) - `latest-allowed` The `latest-allowed` strategy rely on [required_version](#required_version) from .tf or .tf.json files with a fallback to `latest` when no constraint are found. Moreover it is possible to add a default constraint with TOFUENV_TOFU_DEFAULT_CONSTRAINT environment variable or `${TENV_ROOT}/OpenTofu/constraint` file (can be written with `tenv tofu constraint`). The default constraint is added while using `latest-allowed`, `min-required` or custom constraint. A default constraint with `latest-allowed` or `min-required` will avoid the fallback to `latest` when there is no .tf or .tf.json files.
terraform
The `terraform` command in this project is a proxy to HashiCorp's `terraform` command managed by **tenv**. The version resolution order is : - TFENV_TERRAFORM_VERSION environment variable - `.terraform-version` file - `.tfswitchrc` file - `terraform_version_constraint` from `terragrunt.hcl` file - `terraform_version_constraint` from `terragrunt.hcl.json` file - TFENV_TERRAFORM_DEFAULT_VERSION environment variable - `${TENV_ROOT}/Terraform/version` file (can be written with `tenv tf use`) - `latest-allowed` The `latest-allowed` strategy rely on [required_version](#required_version) from .tf or .tf.json files with a fallback to `latest` when no constraint are found. Moreover it is possible to add a default constraint with TFENV_TERRAFORM_DEFAULT_CONSTRAINT environment variable or `${TENV_ROOT}/Terraform/constraint` file (can be written with `tenv tf constraint`). The default constraint is added while using `latest-allowed`, `min-required` or custom constraint. A default constraint with `latest-allowed` or `min-required` will avoid the fallback to `latest` when there is no .tf or .tf.json files.
terragrunt
The `terragrunt` command in this project is a proxy to Gruntwork's `terragrunt` command managed by **tenv**. The version resolution order is : - TG_VERSION environment variable - `.terragrunt-version` file - `.tgswitchrc` file - `version` from `tgswitch.toml` file - `terragrunt_version_constraint` from `terragrunt.hcl` file - `terragrunt_version_constraint` from `terragrunt.hcl.json` file - TG_DEFAULT_VERSION environment variable - `${TENV_ROOT}/Terragrunt/version` file (can be written with `tenv tg use`) - `latest-allowed` The `latest-allowed` strategy has no information for Terragrunt and will fallback to `latest` unless there is default constraint. Adding a default constraint could be done with TG_DEFAULT_CONSTRAINT environment variable or `${TENV_ROOT}/Terragrunt/constraint` file (can be written with `tenv tg constraint`). The default constraint is added while using `latest-allowed`, `min-required` or custom constraint. A default constraint with `latest-allowed` or `min-required` will avoid there fallback to `latest`.
tf
The `tf` command is a proxy to `tofu` or `terraform` depending on the version files present in project. The version resolution order is : - `.opentofu-version` file (launch `tofu`) - `terraform_version_constraint` from `terragrunt.hcl` file (launch `tofu`) - `terraform_version_constraint` from `terragrunt.hcl.json` file (launch `tofu`) - `.terraform-version` file (launch `terraform`) - `.tfswitchrc` file (launch `terraform`) - fail with a message
### Advanced remote configuration This advanced configuration is meant to call artifact mirror (like [JFrog Artifactory](https://jfrog.com/artifactory)). The yaml file from TENV_REMOTE_CONF path can have one part for each supported proxy : `tofu`, `terraform` and `terragrunt`.
yaml fields description
Each part can have the following string field : `install_mode`, `list_mode`, `list_url`, `url`, `new_base_url`, `old_base_url`, `selector` and `part` With `install_mode` set to "direct", **tenv** skip the release information fetching and generate download url instead of reading them from API (overridden by `_INSTALL_MODE` env var). With `list_mode` set to "html", **tenv** change the fetching of all releases information from API to parse the parent html page of artifact location, see `selector` and `part` (overridden by `_LIST_MODE` env var). `url` allows to override the default remote url (overridden by flag or `_REMOTE` env var). `list_url` allows to override the remote url only for the releases listing (overridden by `_LIST_URL` env var). `old_base_url` and `new_base_url` are used as url rewrite rule (if an url start with the prefix, it will be changed to use the new base url). If `old_base_url` and `new_base_url` are empty, **tenv** try to guess right behaviour based on previous fields. `selector` is used to gather in a list all matching html node and `part` choose on which node part (attribute name or "#text" for inner text) a version will be extracted (selector default to "a" (html link) and part default to "href" (link target)) </details>
Examples
Those examples assume that a GitHub proxy at https://artifactory.example.com/artifactory/github have the same behavior than [JFrog Artifactory](https://jfrog.com/artifactory) : - mirror https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_linux_amd64.zip at https://artifactory.example.com/artifactory/github/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_linux_amd64.zip. - have at https://artifactory.example.com/artifactory/github/opentofu/opentofu/releases/download an html page with links on existing sub folder like "v1.6.0/" Example 1 : Retrieve Terraform binaries and list available releases from the mirror. ```console TFENV_REMOTE=https://artifactory.example.com/artifactory/hashicorp TFENV_LIST_MODE=html ``` Example 2 : Retrieve Terraform binaries from the mirror and list available releases from the Hashicorp releases API (TFENV_LIST_URL is optional because it default to https://releases.hashicorp.com with the default list mode "api"). ```console TFENV_REMOTE=https://artifactory.example.com/artifactory/hashicorp TFENV_LIST_URL=https://releases.hashicorp.com ``` Example 1 & 2, does not need install mode (by release index.json is figed in mirror without problem), however create a rewrite rule from "https://releases.hashicorp.com" to "https://artifactory.example.com/artifactory/hashicorp" to obtains correct download URLs. Example 3 : Retrieve OpenTofu binaries and list available releases from the mirror (TOFUENV_INSTALL_MODE is optional because overloading TOFUENV_REMOTE already set it to "direct"). ```console TOFUENV_REMOTE=https://artifactory.example.com/artifactory/github TOFUENV_INSTALL_MODE=direct TOFUENV_LIST_MODE=html ``` Example 4 : Retrieve OpenTofu binaries from the mirror and list available releases from the GitHub API (TOFUENV_INSTALL_MODE is optional because overloading TOFUENV_REMOTE already set it to "direct", and TOFUENV_LIST_URL is optional because it default to https://api.github.com/repos/opentofu/opentofu/releases with the default list mode "api"). ```console TOFUENV_REMOTE=https://artifactory.example.com/artifactory/github TOFUENV_INSTALL_MODE=direct TOFUENV_LIST_URL=https://api.github.com/repos/opentofu/opentofu/releases ``` Example 3 & 4, does not create a rewrite rule (the direct install mode build correct download URLs). Example 1 & 4 can be merged in a remote.yaml : ```yaml tofu: url: "https://artifactory.example.com/artifactory/github" install_mode: "direct" list_url: "https://api.github.com/repos/opentofu/opentofu/releases" terraform: url: "https://artifactory.example.com/artifactory/hashicorp" list_mode: "html" ```
### Signature support
OpenTofu signature support
**tenv** checks the sha256 checksum and the signature of the checksum file with [cosign](https://github.com/sigstore/cosign) (if present on your machine) or PGP (via [gopenpgp](https://github.com/ProtonMail/gopenpgp)). However, unstable OpenTofu versions are signed only with cosign (in this case, if cosign is not found tenv will display a warning).
Terraform signature support
**tenv** checks the sha256 checksum and the PGP signature of the checksum file (via [gopenpgp](https://github.com/ProtonMail/gopenpgp), there is no cosign signature available).
Terragrunt signature support
**tenv** checks the sha256 checksum (there is no signature available).
## Contributing Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again! 1. Fork the Project 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 4. Push to the Branch (`git push origin feature/AmazingFeature`) 5. Open a Pull Request

(back to top)

## Community Have questions or suggestions? Reach out to us via: * [GitHub Issues](LINK_TO_ISSUES) * User/Developer Group: Join github community to get update of Harbor's news, features, releases, or to provide suggestion and feedback. * Slack: Join tofuutils's community for discussion and ask questions: OpenTofu, channel: #tofuutils ## Authors tenv is based on [tofuenv](https://github.com/tofuutils/tofuenv) and [gotofuenv](https://github.com/tofuutils/gotofuenv) projects and supported by tofuutils team with help from these awesome contributors: Star History Chart ## LICENSE The tenv project is distributed under the Apache 2.0 license. See [LICENSE](/tenv/LICENSE).