Infrastructure
OpenTofu, Terraform, Terragrunt, and Atmos version manager, written in Go.
·
Report Bug
·
Request Feature
Welcome to tenv, a versatile version manager for OpenTofu, Terraform, Terragrunt and Atmos, 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.
asdf-vm share the same goals than tenv : simplify the usage of several version of tools.
asdf-vm is generic and extensible with a plugin system, key tenv differences :
If you need to enable cosign checks, install cosign
(v.2.0+) tool via one of the following commands:
brew install cosign
go install github.com/sigstore/cosign/v2/cmd/cosign@latest
apk add cosign
sudo pacman -S cosign
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}-1.x86_64.rpm
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
This package is available on the Arch Linux User Repository. It can be installed using the yay AUR helper:
yay tenv-bin
Installation via Nix package manager:
nix-env -i tenv
brew install tenv
Installation via Nix package manager:
nix-env -i tenv
Installation via Chocolatey:
choco install tenv
Installation via Scoop:
scoop install tenv
Installation via Nix package manager:
nix-env -i tenv
snap install tenv
apk add tenv --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
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"
Installation via Nix package manager:
nix-env -i tenv
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
.
You can use dockerized version of tenv via the following command:
docker run -it --rm 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.
[!NOTE] If you install tenv via Brew or Nix, completion will be installed automatically.
tenv completion zsh > ~/.tenv.completion.zsh
echo "source \$HOME/.tenv.completion.zsh" >> ~/.zshrc
tenv completion zsh > ~/.oh-my-zsh/completions/_tenv
Make sure the completions folder ~/.oh-my-zsh/completions
is listed under $fpath
:
print -l $fpath
tenv completion powershell | Out-String | Invoke-Expression
tenv completion bash > ~/.tenv.completion.bash
echo "source \$HOME/.tenv.completion.bash" >> ~/.bashrc
tenv completion fish > ~/.tenv.completion.fish
echo "source \$HOME/.tenv.completion.fish" >> ~/.config/fish/config.fish
tenv supports OpenTofu,
Terragrunt, Terraform and
Atmos. 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 |
at (atmos ) | ATMOS_ | Atmos |
Without subcommand tenv
display interactive menus to manage tools and their versions.
Install a requested version of the tool (into TENV_ROOT
directory from <TOOL>_REMOTE
url).
Without a parameter, the version to use is resolved automatically (see resolution order in tools description, with latest
as default in place of latest-allowed
).
If a parameter is passed, available options include:
<TOOL>_REMOTE
url).latest
, latest-stable
(old name of latest
) or latest-pre
(include unstable version), which are checked against versions available at <TOOL>_REMOTE
url.latest:<re>
or min:<re>
to get first version matching with <re>
as a regexp 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 docs.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 atmos install "~> 1.70"
tenv atmos install latest
tenv <tool> install latest-allowed
tenv <tool> install min-required
A complete display :
$ 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
Switch the default tool version to use (set in TENV_ROOT/<TOOL>/version
file).
tenv <tool> use
has a --working-dir
, -w
flag to write a version file in working directory.
Available parameter options:
latest
, latest-stable
(old name of latest
) or latest-pre
(include unstable version), which are checked against versions available in TENV_ROOT directory.latest:<re>
or min:<re>
to get first version matching with <re>
as a regexp 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 docs.tenv tofu use v1.6.0-beta5
tenv tf use min-required
tenv tg use latest
tenv atmos use latest
tenv tofu use latest-allowed
Detect the used version of tool for the working directory.
$ 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 atmos detect -q
Atmos 1.72.0 will be run from this directory.
Reset used version of tool (remove TENV_ROOT/<TOOL>/version
file).
$ tenv tofu reset
Removed /home/dvaumoron/.tenv/OpenTofu/version
Uninstall versions of the tool (remove it from TENV_ROOT
directory).
Without parameter, display an interactive list to select several versions.
If a parameter is passed, available parameter options:
all
but-last
(all versions except the highest installed)not-used-for:<duration>
, <duration>
in days or months, like "14d" or "2m"not-used-since:<date>
, <date>
format is YYYY-MM-DD, like "2024-06-30"$ 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)
List installed tool versions (located in TENV_ROOT
directory), sorted in ascending version order.
tenv <tool> list
has a --descending
, -d
flag to sort in descending order.
$ 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.
List installable tool versions (from <TOOL>_REMOTE
url), sorted in ascending version order.
tenv <tool> list-remote
has a --descending
, -d
flag to sort in descending order.
tenv <tool> list-remote
has a --stable
, -s
flag to display only stable version.
$ 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)
Set or reset a default constraint expression for the tool.
$ tenv tf constraint "<= 1.5.7"
Written <= 1.5.7 in /home/dvaumoron/.tenv/Terraform/constraint
Or without expression :
$ tenv tg constraint
Removed /home/dvaumoron/.tenv/Terragrunt/constraint
Help about any command.
You can use --help
-h
flag instead.
$ 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)
$ 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)
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 <tool>
will indicate different locations). The following shell call should resolve such issues :
export PATH=$(tenv update-path)
Display tenv current version.
$ tenv version
tenv version v1.7.0
tenv commands support global environment variables and variables by tool for : OpenTofu, Terraform, TerraGrunt and Atmos.
String (Default: current tenv binaries architecture)
Allow to override the default architecture for binaries downloading during installation.
tenv <tool>
subcommands detect
, install
and use
support a --arch
, -a
flag version.
String (Default: false)
If set to true tenv will automatically install missing tool versions needed.
tenv <tool>
subcommands detect
and use
support a --install
, -i
enabling flag, and a --no-install
, -n
disabling flag.
String (Default: false)
If set to true tenv detection of needed version will skip local check and verify compatibility on remote list.
tenv <tool>
subcommands detect
and use
support a --force-remote
, -f
flag version.
String (Default: "")
Allow to specify a GitHub token to increase GitHub Rate limits for the REST API. Useful because OpenTofu, Terragrunt and Atmos 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.
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.
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".
String (Default: ${TENV_ROOT}/remote.yaml
)
The path to a yaml file for advanced remote configuration (can be used to call artifact mirror).
tenv <tool>
subcommands detect
, install
, list-remote
and use
support a --remote-conf
, -c
flag version.
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.
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. GitHub Actions set it (see default environment variables).
String (Default: "")
Needed when GITHUB_ACTIONS is set to true, path to a file to write proxied output.
String (Default: "")
Used by tenv update-path
when GITHUB_ACTIONS is set to true, path to a file to write tenv directory location.
Same as TENV_AUTO_INSTALL (compatibility with tofuenv).
Use OpenTofu version 1.6.1 that is not installed, and auto installation stay disabled :
$ tenv use 1.6.1
Written 1.6.1 in /home/dvaumoron/.tenv/OpenTofu/version
Use OpenTofu version 1.6.0 that is not installed, and auto installation is enabled :
$ TOFUENV_AUTO_INSTALL=true 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
Same as TENV_FORCE_REMOTE.
String (the default depend on TOFUENV_REMOTE, without change on it, it is "api" else it is "direct")
See advanced remote configuration for more details.
String (the default depend on TOFUENV_LIST_URL, without change on it, it is "api" else it is "html")
See advanced remote configuration for more details.
String (Default: copy TOFUENV_REMOTE, default is overloaded by "https://get.opentofu.org/tofu/api.json" when TOFUENV_LIST_MODE is "mirror")
Allow to override the remote url only for the releases listing.
See advanced remote configuration for more details.
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.
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" and TOFUENV_LIST_MODE is set to "html" (assume an artifact proxy usage).
tenv tofu
subcommands detect
, install
, list-remote
and use
support a --remote-url
, -u
flag version.
See advanced remote configuration for more details.
String (Default: "")
Could be used with TOFUENV_REMOTE_USER to specify HTTP basic auth when same credential are used with TOFUENV_REMOTE and TOFUENV_LIST_URL (instead of https://user:password@host.org
URL format).
String (Default: "")
Could be used with TOFUENV_REMOTE_PASSWORD to specify HTTP basic auth when same credential are used with TOFUENV_REMOTE and TOFUENV_LIST_URL (instead of https://user:password@host.org
URL format).
String (Default: https://github.com/opentofu/opentofu/releases/download/v{{ .Version }}/{{ .Artifact }}
)
Used when TOFUENV_INSTALL_MODE is "mirror" (see TofuDL mirror specification).
String (Default: "")
If not empty string, this variable overrides OpenTofu default constraint, specified in ${TENV_ROOT}/OpenTofu/constraint file.
String (Default: "")
If not empty string, this variable overrides OpenTofu fallback version, specified in ${TENV_ROOT}/OpenTofu/version file.
String (Default: "")
If not empty string, this variable overrides OpenTofu version, specified in .opentofu-version
files.
tenv tofu
subcommands install
and detect
also respects this variable.
e.g. with :
$ tofu version
OpenTofu v1.6.1
on linux_amd64
then :
$ TOFUENV_TOFU_VERSION=1.6.0 tofu version
OpenTofu v1.6.0
on linux_amd64
Same as TENV_FORCE_REMOTE.
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.
String (Default: "api")
See advanced remote configuration for more details.
String (the default depend on TFENV_LIST_URL, without change on it, it is "api" else it is "html")
See advanced remote configuration for more details.
String (Default: copy TFENV_REMOTE)
Allow to override the remote url only for the releases listing.
See advanced remote configuration for more details.
String (Default: https://releases.hashicorp.com)
URL to install Terraform, changing it assume an artifact proxy use (TFENV_LIST_URL copy it, and if it differ from its default value, TFENV_LIST_MODE is set to "html", because an artifact proxy usage will not disturb the retrieving of index.json for a release, but will freeze the json list of releases).
tenv tf
subcommands detect
, install
, list-remote
and use
support a --remote-url
, -u
flag version.
See advanced remote configuration for more details.
String (Default: "")
Could be used with TFENV_REMOTE_USER to specify HTTP basic auth when same credential are used with TFENV_REMOTE and TFENV_LIST_URL (instead of https://user:password@host.org
URL format).
String (Default: "")
Could be used with TFENV_REMOTE_PASSWORD to specify HTTP basic auth when same credential are used with TFENV_REMOTE and TFENV_LIST_URL (instead of https://user:password@host.org
URL format).
String (Default: "")
If not empty string, this variable overrides Terraform default constraint, specified in ${TENV_ROOT}/Terraform/constraint file.
String (Default: "")
If not empty string, this variable overrides Terraform fallback version, specified in ${TENV_ROOT}/Terraform/version file.
String (Default: "")
If not empty string, this variable overrides Terraform version, specified in .terraform-version
files.
tenv tf
subcommands install
and detect
also respects this variable.
e.g. with :
$ terraform version
Terraform v1.7.2
on linux_amd64
then :
$ 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
String (the default depend on TG_REMOTE, without change on it, it is "api" else it is "direct")
See advanced remote configuration for more details.
String (the default depend on TG_LIST_URL, without change on it, it is "api" else it is "html")
See advanced remote configuration for more details.
String (Default: copy TG_REMOTE)
Allow to override the remote url only for the releases listing.
See advanced remote configuration for more details.
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" and TG_LIST_MODE is set to "html" (assume an artifact proxy usage).
tenv tg
subcommands detect
, install
, list-remote
and use
support a --remote-url
, -u
flag version.
See advanced remote configuration for more details.
String (Default: "")
Could be used with TG_REMOTE_USER to specify HTTP basic auth when same credential are used with TG_REMOTE and TG_LIST_URL (instead of https://user:password@host.org
URL format).
String (Default: "")
Could be used with TG_REMOTE_PASSWORD to specify HTTP basic auth when same credential are used with TG_REMOTE and TG_LIST_URL (instead of https://user:password@host.org
URL format).
String (Default: "")
If not empty string, this variable overrides Terragrunt default constraint, specified in ${TENV_ROOT}/Terragrunt/constraint file.
String (Default: "")
If not empty string, this variable overrides Terragrunt fallback version, specified in ${TENV_ROOT}/Terragrunt/version file.
String (Default: "")
If not empty string, this variable overrides Terragrunt version, specified in .terragrunt-version
files.
tenv tg
subcommands install
and detect
also respects this variable.
e.g. with :
$ terragrunt -v
terragrunt version v0.55.1
then :
$ TG_VERSION=0.54.1 terragrunt -v
terragrunt version v0.54.1
String (the default depend on ATMOS_REMOTE, without change on it, it is "api" else it is "direct")
See advanced remote configuration for more details.
String (the default depend on ATMOS_LIST_URL, without change on it, it is "api" else it is "html")
See advanced remote configuration for more details.
String (Default: copy ATMOS_REMOTE)
Allow to override the remote url only for the releases listing.
See advanced remote configuration for more details.
String (Default: https://api.github.com/repos/cloudposse/atmos/releases)
URL to install Atmos when ATMOS_REMOTE differ from its default value, ATMOS_INSTALL_MODE is set to "direct" and ATMOS_LIST_MODE is set to "html" (assume an artifact proxy usage).
tenv atmos
subcommands detect
, install
, list-remote
and use
support a --remote-url
, -u
flag version.
See advanced remote configuration for more details.
String (Default: "")
Could be used with ATMOS_REMOTE_USER to specify HTTP basic auth when same credential are used with ATMOS_REMOTE and ATMOS_LIST_URL (instead of https://user:password@host.org
URL format).
String (Default: "")
Could be used with ATMOS_REMOTE_PASSWORD to specify HTTP basic auth when same credential are used with ATMOS_REMOTE and ATMOS_LIST_URL (instead of https://user:password@host.org
URL format).
String (Default: "")
If not empty string, this variable overrides Atmos default constraint, specified in ${TENV_ROOT}/Atmos/constraint file.
String (Default: "")
If not empty string, this variable overrides Atmos fallback version, specified in ${TENV_ROOT}/Atmos/version file.
String (Default: "")
If not empty string, this variable overrides Atmos version, specified in .atmos-version
files.
tenv atmos
subcommands install
and detect
also respects this variable.
e.g. with :
$ atmos version
👽 Atmos v1.72.0 on linux/amd64
then :
$ ATMOS_VERSION=1.70 atmos version
👽 Atmos v1.70.0 on linux/amd64
The TENV_ROOT/<TOOL>/version
file is the tool default version used when no project specific or user specific are found. It can be written with tenv <tool> use
.
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 docs.
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 docs.
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.
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).
If you put a .atmos-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 ATMOS_VERSION can be used to override version specified by those files.
Recognize same values as tenv atmos use
command.
the latest-allowed
or min-required
strategies scan through your IAC files (see list in project binaries) 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, and can optionally be used with a default constraint as detailed in project binaries.
Currently the format for Terraform required_version and OpenTofu required_version are very similar, however this may change over time, always refer to docs for the latest format specification.
example:
version = ">= 1.2.0, < 2.0.0"
This would identify the latest version at or above 1.2.0 and below 2.0.0
The tofu
command in this project is a proxy to OpenTofu's tofu
command managed by tenv.
The version resolution order is :
.opentofu-version
fileterraform_version_constraint
from terragrunt.hcl
fileterraform_version_constraint
from terragrunt.hcl.json
file${TENV_ROOT}/OpenTofu/version
file (can be written with tenv tofu use
)latest-allowed
The latest-allowed
strategy rely on required_version from .tofu, .tofu.json, .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.
The terraform
command in this project is a proxy to HashiCorp's terraform
command managed by tenv.
The version resolution order is :
.terraform-version
file.tfswitchrc
fileterraform_version_constraint
from terragrunt.hcl
fileterraform_version_constraint
from terragrunt.hcl.json
file${TENV_ROOT}/Terraform/version
file (can be written with tenv tf use
)latest-allowed
The latest-allowed
strategy rely on 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.
The terragrunt
command in this project is a proxy to Gruntwork's terragrunt
command managed by tenv.
The version resolution order is :
.terragrunt-version
file.tgswitchrc
fileversion
from tgswitch.toml
fileterragrunt_version_constraint
from terragrunt.hcl
fileterragrunt_version_constraint
from terragrunt.hcl.json
file${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
.
The atmos
command in this project is a proxy to Cloudposse's atmos
command managed by tenv.
The version resolution order is :
.atmos-version
file${TENV_ROOT}/Atmos/version
file (can be written with tenv atmos use
)latest-allowed
The latest-allowed
strategy has no information for Atmos and will fallback to latest
unless there is default constraint. Adding a default constraint could be done with
ATMOS_DEFAULT_CONSTRAINT environment variable or ${TENV_ROOT}/Atmos/constraint
file (can
be written with tenv atmos 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
.
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
)This advanced configuration is meant to call artifact mirror (like JFrog Artifactory).
The yaml file from TENV_REMOTE_CONF path can have one part for each supported proxy : tofu
, terraform
, terragrunt
and atmos
.
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 <TOOL>_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 <TOOL>_LIST_MODE
env var).
url
allows to override the default remote url (overridden by flag or <TOOL>_REMOTE
env var).
list_url
allows to override the remote url only for the releases listing (overridden by <TOOL>_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))
Those examples assume that a GitHub proxy at https://artifactory.example.com/artifactory/github have the same behavior than JFrog Artifactory :
Example 1 : Retrieve Terraform binaries and list available releases from the mirror (TFENV_LIST_MODE is optional because TFENV_LIST_URL differ from its default(when TFENV_LIST_URL is not set, it copy TFENV_REMOTE)).
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_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 and TOFUENV_LIST_MODE are optional because overloading TOFUENV_REMOTE already change them).
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").
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 :
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"
tenv checks the sha256 checksum and the signature of the checksum file with cosign (if present on your machine) or PGP (via gopenpgp). However, unstable OpenTofu versions are signed only with cosign (in this case, if cosign is not found tenv will display a warning).
tenv checks the sha256 checksum and the PGP signature of the checksum file (via gopenpgp, there is no cosign signature available).
tenv checks the sha256 checksum (there is no signature available).
tenv checks the sha256 checksum (there is no signature available).
You can use cosign
to verify the signature of tenv
releases. Below is an example installing the .rpm
using dnf
once we've verified the signatures/integrity.
[!NOTE] The example below is a bash script that could be useful if you are wanting to automate installation of
tenv
in a developer environment. Adapt it to fit your specific use case.
# Get latest release
LATEST_VERSION=$(curl --silent https://api.github.com/repos/tofuutils/tenv/releases/latest | jq -r .tag_name) #v2.6.1
# Get checksum files
curl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_checksums.txt
curl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_checksums.txt.sig
curl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_checksums.txt.pem
# Get RPM files
curl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_amd64.rpm
curl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_amd64.rpm.sig
curl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_amd64.rpm.pem
# Verify signatures
cosign \
verify-blob \
--certificate-identity "https://github.com/tofuutils/tenv/.github/workflows/release.yml@refs/tags/${LATEST_VERSION}" \
--signature "tenv_${LATEST_VERSION}_checksums.txt.sig" \
--certificate "tenv_${LATEST_VERSION}_checksums.txt.pem" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"tenv_${LATEST_VERSION}_checksums.txt"
TENV_SIG_CHECK=$?
cosign \
verify-blob \
--certificate-identity "https://github.com/tofuutils/tenv/.github/workflows/release.yml@refs/tags/${LATEST_VERSION}" \
--signature "tenv_${LATEST_VERSION}_amd64.rpm.sig" \
--certificate "tenv_${LATEST_VERSION}_amd64.rpm.pem" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"tenv_${LATEST_VERSION}_amd64.rpm"
TENV_ASSET_CHECK=$?
# Check everything is good before installation
if [ "$TENV_SIG_CHECK" -eq "0" ] && [ "$TENV_ASSET_CHECK" -eq "0" ] && shasum -a 256 -c "tenv_${LATEST_VERSION}_checksums.txt" --ignore-missing
then
dnf install "tenv_${LATEST_VERSION}_amd64.rpm" -y
tenv --version
else
echo "Signature verification and/or checksum checks failed!"
fi
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
Check out our contributing guide to get started.
Don't forget to give the project a star! Thanks again!
Have questions or suggestions? Reach out to us via:
tenv is based on tofuenv and gotofuenv projects and supported by tofuutils team with help from these awesome contributors:
The tenv project is distributed under the Apache 2.0 license. See LICENSE.