{"id":13505852,"url":"https://github.com/tofuutils/tenv","last_synced_at":"2026-01-25T22:15:34.919Z","repository":{"id":215940538,"uuid":"739378779","full_name":"tofuutils/tenv","owner":"tofuutils","description":"OpenTofu / Terraform / Terragrunt and Atmos version manager","archived":false,"fork":false,"pushed_at":"2025-05-09T22:49:18.000Z","size":45046,"stargazers_count":1037,"open_issues_count":27,"forks_count":44,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-09T23:27:39.645Z","etag":null,"topics":["go","hacktoberfest","hacktoberfest2024","hashicorp","hashicorp-terraform","iac","opentofu","tenv","terraform","tfenv","tofu","tofuenv"],"latest_commit_sha":null,"homepage":"https://tofuutils.github.io/tenv/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tofuutils.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-01-05T12:25:20.000Z","updated_at":"2025-05-09T22:34:33.000Z","dependencies_parsed_at":"2024-11-07T14:27:57.671Z","dependency_job_id":"9a1a6d96-2254-440d-af41-6984832db132","html_url":"https://github.com/tofuutils/tenv","commit_stats":{"total_commits":610,"total_committers":18,"mean_commits":"33.888888888888886","dds":"0.34098360655737703","last_synced_commit":"8246b233a6b52cfcdfc1ed498e303f02f49197ee"},"previous_names":["tofuutils/tenv"],"tags_count":134,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tofuutils%2Ftenv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tofuutils%2Ftenv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tofuutils%2Ftenv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tofuutils%2Ftenv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tofuutils","download_url":"https://codeload.github.com/tofuutils/tenv/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101617,"owners_count":22014909,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","hacktoberfest","hacktoberfest2024","hashicorp","hashicorp-terraform","iac","opentofu","tenv","terraform","tfenv","tofu","tofuenv"],"created_at":"2024-08-01T00:01:15.444Z","updated_at":"2026-01-25T22:15:34.910Z","avatar_url":"https://github.com/tofuutils.png","language":"Go","readme":"\u003c!-- BADGES --\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/tofuutils/tenv/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/tofuutils/tenv?style=for-the-badge\" alt=\"Github release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/tofuutils/tenv/graphs/contributors\"\u003e\u003cimg src=\"https://img.shields.io/github/contributors/tofuutils/tenv?style=for-the-badge\" alt=\"Contributors\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/maintenance/yes/2026.svg?style=for-the-badge\" alt=\"maintenance status\"\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/tofuutils/tenv/\"\u003e\u003cimg src=\"https://img.shields.io/badge/go%20report-A+-brightgreen.svg?style=for-the-badge\" alt=\"Go report\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/tofuutils/tenv\"\u003e\u003cimg src=\"https://img.shields.io/codecov/c/github/tofuutils/tenv?token=BDU9X0BAZV\u0026style=for-the-badge\" alt=\"codecov\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\n\u003c!-- LOGO --\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca\u003e\n    \u003cimg src=\"assets/logo.png\" alt=\"Logo\" width=\"200\" height=\"200\"\u003e\n  \u003c/a\u003e\n  \u003ch3 align=\"center\"\u003etenv\u003c/h3\u003e\n  \u003cp align=\"center\"\u003e\n    OpenTofu, Terraform, Terragrunt, Terramate and Atmos version manager, written in Go.\n    \u003cbr /\u003e\n    ·\n    \u003ca href=\"https://github.com/tofuutils/tenv/issues/new?assignees=\u0026labels=issue%3A+bug\u0026projects=\u0026template=bug_report.md\u0026title=\"\u003eReport Bug\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/tofuutils/tenv/issues/new?assignees=\u0026labels=\u0026projects=\u0026template=feature_request.md\u0026title=\"\u003eRequest Feature\u003c/a\u003e\n    ·\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://devhunt.org/tool/tenv\" title=\"DevHunt - Tool of the Week\"\u003e\u003cimg src=\"./assets/devhunt-badge.png\" width=160 alt=\"DevHunt - Tool of the Week\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003ca id=\"about-the-project\"\u003e\u003c/a\u003e\n## About The Project\n\nWelcome to **tenv**, a versatile version manager for [OpenTofu](https://opentofu.org),\n[Terraform](https://www.terraform.io/), [Terragrunt](https://terragrunt.gruntwork.io/), [Terramate](https://terramate.io/) and\n[Atmos](https://atmos.tools), 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.\n\n**tenv** is a successor of [tofuenv](https://github.com/tofuutils/tofuenv) and [tfenv](https://github.com/tfutils/tfenv).\n\n\u003ca id=\"key-features\"\u003e\u003c/a\u003e\n### Key Features\n\n- Versatile version management: Easily switch between different versions of OpenTofu,\nTerraform, Terragrunt, Terramate and Atmos.\n- [Semver 2.0.0](https://semver.org/) Compatibility: Utilizes [go-version](https://github.com/hashicorp/go-version) for semantic versioning and use the [HCL](https://github.com/hashicorp/hcl) parser to extract required version constraint from OpenTofu/Terraform/Terragrunt files (see [required_version](#required_version) and [Terragrunt hcl](#terragrunt-hcl-file)).\n- Signature verification: Supports [cosign](https://github.com/sigstore/cosign) (if present on your machine) and PGP (via [gopenpgp](https://github.com/ProtonMail/gopenpgp)), see [signature support](#signature-support).\n- Intuitive installation: Simple installation process with Homebrew and manual options.\n- Callable as [Go](https://go.dev) module, with a [Semver compatibility promise](https://semver.org/#summary) on [tenvlib](https://github.com/tofuutils/tenv/tree/main/versionmanager/tenvlib) wrapper package (get more information in [TENV_AS_LIB.md](https://github.com/tofuutils/tenv/blob/main/TENV_AS_LIB.md)).\n\n\u003ca id=\"difference-with-asdf\"\u003e\u003c/a\u003e\n### Difference with asdf\n\n[asdf-vm](https://asdf-vm.com/) share the same goals than **tenv** : simplify the usage of several version of tools.\n\nasdf-vm is generic and extensible with a plugin system, key **tenv** differences :\n- **tenv** is more specific and has features dedicated to OpenTofu, Terraform, Terragrunt, Terramate \nand Atmos, like [HCL](https://github.com/hashicorp/hcl) parsing based detection (see [Key Features](#key-features)).\n- **tenv** is distributed as independent binaries and does not rely on any shell or other CLI executable.\n- **tenv** does better in terms of performance and platform compatibility. It works uniformly across all modern operating systems,\nincluding Linux, MacOS, Windows, BSD, and Solaris, whereas asdf-vm natively supports only Linux and MacOS.\n- **tenv** checks the sha256 checksum and the signature of the checksum file with [cosign](https://github.com/sigstore/cosign). Check [Signature support](#signature-support) section for getting more information about it.\n- **tenv** command compatibility: In nearly all places you can use the exact syntax that works in tfenv / tofuenv.\nIf you're coming from tfenv/tofuenv and comfortable with that way of working you can almost always use the same syntax with tenv.\n- **tenv** performance: It sounds incredibly useful, though it might be tough to get a real apples to apples comparison since the\ntools work differently in a lot of ways. The author of asdf did a great writeup of performance problems.\n\n\u003ca id=\"table-of-contents\"\u003e\u003c/a\u003e\n## Table of Contents\n\u003c!-- TABLE OF CONTENTS --\u003e\n\u003cdetails markdown=\"1\"\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n  \u003col\u003e\n    \u003cli\u003e\n      \u003ca href=\"#about-the-project\"\u003eAbout The Project\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#key-features\"\u003eKey Features\u003c/a\u003e\u003c/li\u003e\n        \u003cli\u003e\u003ca href=\"#difference-with-asdf\"\u003eDifference with asdf\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\n        \u003ca href=\"#table-of-contents\"\u003eTable of contents\u003c/a\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\n      \u003ca href=\"#getting-started\"\u003eGetting Started\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#prerequisites\"\u003ePrerequisites\u003c/a\u003e\u003c/li\u003e\n        \u003cli\u003e\u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#environment-variables\"\u003eEnvironment variables\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#version-files\"\u003eVersion files\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#technical-details\"\u003eTechnical details\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#verifying-signature\"\u003eVerifying tenv Signatures\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#community\"\u003eCommunity\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#authors\"\u003eAuthors\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#licence\"\u003eLicence\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/details\u003e\n\n\n\u003ca id=\"getting-started\"\u003e\u003c/a\u003e\n## Getting Started\n\n\u003ca id=\"prerequisites\"\u003e\u003c/a\u003e\n### Prerequisites\nIf you need to enable cosign checks, install `cosign` (v.2.0+) tool via one of the following commands:\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eMacOS (Homebrew, MacPorts)\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nInstallation via Homebrew:\n```sh\nbrew install cosign\n```\n\nInstallation via MacPorts:\n```sh\nsudo port install cosign\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eWindows (go install)\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```sh\ngo install github.com/sigstore/cosign/v2/cmd/cosign@latest\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eAlpine Linux\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```sh\napk add cosign\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eArch Linux\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```sh\nsudo pacman -S cosign\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eLinux: RPM\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```sh\nLATEST_VERSION=$(curl https://api.github.com/repos/sigstore/cosign/releases/latest | jq -r .tag_name | tr -d \"v\")\ncurl -O -L \"https://github.com/sigstore/cosign/releases/latest/download/cosign-${LATEST_VERSION}-1.x86_64.rpm\"\nsudo rpm -ivh cosign-${LATEST_VERSION}-1.x86_64.rpm\n```\n\n\u003c/details\u003e\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eLinux: dkpg\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```sh\nLATEST_VERSION=$(curl https://api.github.com/repos/sigstore/cosign/releases/latest | jq -r .tag_name | tr -d \"v\")\ncurl -O -L \"https://github.com/sigstore/cosign/releases/latest/download/cosign_${LATEST_VERSION}_amd64.deb\"\nsudo dpkg -i cosign_${LATEST_VERSION}_amd64.deb\n```\n\n\u003c/details\u003e\n\n\n\u003ca id=\"installation\"\u003e\u003c/a\u003e\n### Installation\n\n\u003ca id=\"automatic-installation\"\u003e\u003c/a\u003e\n#### Automatic Installation\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eArch Linux (AUR, Nix)\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThis package is available on the Arch Linux User Repository.\nIt can be installed using the yay AUR helper:\n```sh\nyay tenv-bin\n```\n\nInstallation via Nix package manager:\n```sh\nnix-env -i tenv\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eMacOS (Homebrew, MacPorts, Nix)\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nInstallation via Homebrew:\n```console\nbrew install tenv\n```\n\nInstallation via MacPorts:\n```console\nsudo port install tenv\n```\n\nInstallation via Nix package manager:\n```console\nnix-env -i tenv\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eWindows (Chocolatey, Scoop, Nix)\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nInstallation via Chocolatey:\n```console\nchoco install tenv\n```\n\nInstallation via Scoop:\n```console\nscoop install tenv\n```\n\nInstallation via Nix package manager:\n```console\nnix-env -i tenv\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eLinux: Snapcraft\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```sh\nsnap install tenv\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eAlpine\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```sh\napk add tenv --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/\n```\n\n#### Installation via Cloudsmith Artifact Management platform.\n\nSetup Cloudsmith repository [automatically](https://help.cloudsmith.io/docs/alpine-repository#public-repositories):\n```sh\nsudo apk add --no-cache bash\ncurl -1sLf 'https://dl.cloudsmith.io/public/tofuutils/tenv/cfg/setup/bash.alpine.sh' | sudo bash\n```\nInstall via apk:\n```sh\napk add tenv\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eUbuntu\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n#### Install via dpkg\n\n```sh\nLATEST_VERSION=$(curl --silent https://api.github.com/repos/tofuutils/tenv/releases/latest | jq -r .tag_name)\ncurl -O -L \"https://github.com/tofuutils/tenv/releases/latest/download/tenv_${LATEST_VERSION}_amd64.deb\"\nsudo dpkg -i \"tenv_${LATEST_VERSION}_amd64.deb\"\n```\n\n#### Install via Nix\nInstallation via Nix package manager:\n```console\nnix-env -i tenv\n```\n\n#### Installation via Cloudsmith Artifact Management platform.\nSetup Cloudsmith repository [automatically](https://help.cloudsmith.io/docs/debian-repository#public-repositories):\n```sh\ncurl -1sLf 'https://dl.cloudsmith.io/public/tofuutils/tenv/cfg/setup/bash.deb.sh' | sudo bash\n```\nInstall via apt:\n```sh\nsudo apt install tenv\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eRedHat\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n#### Installation via Cloudsmith Artifact Management platform.\nSetup Cloudsmith repository [automatically](https://help.cloudsmith.io/docs/redhat-repository#public-repositories):\n```sh\ncurl -1sLf 'https://dl.cloudsmith.io/public/tofuutils/tenv/cfg/setup/bash.rpm.sh' | sudo bash\n```\nInstall via yum:\n```sh\nsudo yum install tenv\n```\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eNixOS\u003c/b\u003e\u003c/summary\u003e\n\n#### nix-env\n\n```sh\nnix-env -iA nixos.tenv\n```\n\n#### NixOS Configuration\nAdd the following Nix code to your NixOS Configuration, usually located in /etc/nixos/configuration.nix\n```console\nenvironment.systemPackages = [\n    pkgs.tenv\n  ];\n```\n#### nix-shell\n\n```sh\nnix-shell -p tenv\n```\n\u003c/details\u003e\n\n\u003ca id=\"manual-installation\"\u003e\u003c/a\u003e\n#### Manual Installation\nGet the most recent packaged binaries (`.deb`, `.rpm`, `.apk`, `pkg.tar.zst `, `.zip` or `.tar.gz` format) by visiting the [release page](https://github.com/tofuutils/tenv/releases). After downloading, unzip the folder and seamlessly integrate it into your system's `PATH`.\n\n\u003ca id=\"docker-installation\"\u003e\u003c/a\u003e\n\n#### Docker Installation\n\nYou can use dockerized version of tenv via the following command:\n\n```sh\ndocker run -it --rm tofuutils/tenv:latest help\n```\nThe 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](#manual-installation).\n\u003ca id=\"usage\"\u003e\u003c/a\u003e\n\n\u003ca id=\"shell-completion\"\u003e\u003c/a\u003e\n### Install shell completion\n\n\u003e [!NOTE]\n\u003e If you install tenv via Brew, MacPorts, or Nix, completion will be installed automatically.\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003ezsh\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```console\ntenv completion zsh \u003e ~/.tenv.completion.zsh\necho \"source \\$HOME/.tenv.completion.zsh\" \u003e\u003e ~/.zshrc\n```\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eOh My Zsh\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```console\ntenv completion zsh \u003e ~/.oh-my-zsh/completions/_tenv\n```\n\nMake sure the completions folder `~/.oh-my-zsh/completions` is listed under `$fpath`:\n\n```console\nprint -l $fpath\n```\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003epowershell\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```console\ntenv completion powershell | Out-String | Invoke-Expression\n```\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003ebash\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```console\ntenv completion bash \u003e ~/.tenv.completion.bash\necho \"source \\$HOME/.tenv.completion.bash\" \u003e\u003e ~/.bashrc\n```\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003efish\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n```console\ntenv completion fish \u003e ~/.tenv.completion.fish\necho \"source \\$HOME/.tenv.completion.fish\" \u003e\u003e ~/.config/fish/config.fish\n```\n\u003c/details\u003e\n\n## Usage\n\n**tenv** supports [OpenTofu](https://opentofu.org),\n[Terraform](https://www.terraform.io/), [Terragrunt](https://terragrunt.gruntwork.io/), [Terramate](https://terramate.io/) and\n[Atmos](https://atmos.tools). To manage each binary you can use `tenv \u003ctool\u003e \u003ccommand\u003e`. Below is a list of tools and commands that use actual subcommands:\n\n| tool (alias)        | env vars                   | description                                    |\n| ------------------- | -------------------------- | ---------------------------------------------- |\n| `tofu` (`opentofu`) | [TOFUENV_](#tofu-env-vars) | [OpenTofu](https://opentofu.org)               |\n| `tf` (`terraform`)  | [TFENV_](#tf-env-vars)     | [Terraform](https://www.terraform.io/)         |\n| `tg` (`terragrunt`) | [TG_](#tg-env-vars)        | [Terragrunt](https://terragrunt.gruntwork.io/) |\n| `tm` (`terramate`)  | [TM_](#tm-env-vars)        | [Terramate](https://terramate.io/)             |\n| `at` (`atmos`)      | [ATMOS_](#atmos-env-vars)  | [Atmos](https://atmos.tools)                   |\n\n\nWithout subcommand `tenv` display interactive menus to manage tools and their versions.\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://asciinema.org/a/670790\"\u003e\n    \u003cimg alt=\"tenv interactive\" src=\"https://raw.githubusercontent.com/tofuutils/tenv/main/assets/tenv.gif\" width=\"100%\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv \u0026lt;tool\u0026gt; install [version]\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nInstall a requested version of the tool (into `TENV_ROOT` directory from `\u003cTOOL\u003e_REMOTE` url).\n\nWithout 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`).\n\nIf a parameter is passed, available options include:\n\n- an exact [Semver 2.0.0](https://semver.org/) version string to install.\n- a [version constraint](https://opentofu.org/docs/language/expressions/version-constraints) string (checked against versions available at `\u003cTOOL\u003e_REMOTE` url).\n- `latest`, `latest-stable` (old name of `latest`) or `latest-pre` (include unstable version), which are checked against versions available at `\u003cTOOL\u003e_REMOTE` url.\n- `latest:\u003cre\u003e` or `min:\u003cre\u003e` to get first version matching with `\u003cre\u003e` as a [regexp](https://github.com/google/re2/wiki/Syntax) after a descending or ascending version sort.\n- `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.\n\n```console\ntenv tofu install\ntenv tofu install 1.6.0-beta5\ntenv tf install \"~\u003e 1.6.0\"\ntenv tf install latest-pre\ntenv tg install latest\ntenv tg install latest-stable\ntenv atmos install \"~\u003e 1.70\"\ntenv atmos install latest\ntenv \u003ctool\u003e install latest-allowed\ntenv \u003ctool\u003e install min-required\n```\n\nA complete display :\n\n```console\n$ tenv tofu install 1.6.0\nInstalling OpenTofu 1.6.0\nFetching release information from https://api.github.com/repos/opentofu/opentofu/releases/tags/v1.6.0\nDownloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_linux_amd64.zip\nDownloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS\nDownloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS.sig\nDownloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS.pem\nInstallation of OpenTofu 1.6.0 successful\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv \u0026lt;tool\u0026gt; use  \u0026lt;version\u0026gt;\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSwitch the default tool version to use (set in `TENV_ROOT/\u003cTOOL\u003e/version` file).\n\n`tenv \u003ctool\u003e use` has a `--working-dir`, `-w` flag to write a [version file](#version-files) in working directory.\n\nAvailable parameter options:\n\n- an exact [Semver 2.0.0](https://semver.org/) version string to use.\n- a [version constraint](https://opentofu.org/docs/language/expressions/version-constraints) string (checked against versions available in TENV_ROOT directory).\n- `latest`, `latest-stable` (old name of `latest`) or `latest-pre` (include unstable version), which are checked against versions available in TENV_ROOT directory.\n- `latest:\u003cre\u003e` or `min:\u003cre\u003e` to get first version matching with `\u003cre\u003e` as a [regexp](https://github.com/google/re2/wiki/Syntax) after a descending or ascending version sort.\n- `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.\n\n```console\ntenv tofu use v1.6.0-beta5\ntenv tf use min-required\ntenv tg use latest\ntenv atmos use latest\ntenv tofu use latest-allowed\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv \u0026lt;tool\u0026gt; detect\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nDetect the used version of tool for the working directory.\n\n```console\n$ tenv tofu detect\nNo version files found for OpenTofu, fallback to latest-allowed strategy\nScan project to find .tf files\nNo OpenTofu version requirement found in project files, fallback to latest strategy\nFound compatible version installed locally : 1.6.1\nOpenTofu 1.6.1 will be run from this directory.\n$ tenv tg detect -q\nTerragrunt 0.55.1 will be run from this directory.\n$ tenv atmos detect -q\nAtmos 1.72.0 will be run from this directory.\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv \u0026lt;tool\u0026gt; reset\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nReset used version of tool (remove `TENV_ROOT/\u003cTOOL\u003e/version` file).\n\n```console\n$ tenv tofu reset\nRemoved /home/dvaumoron/.tenv/OpenTofu/version\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv \u0026lt;tool\u0026gt; uninstall [version]\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nUninstall versions of the tool (remove it from `TENV_ROOT` directory).\n\nWithout parameter, display an interactive list to select several versions.\n\nIf a parameter is passed, available parameter options:\n\n- an exact [Semver 2.0.0](https://semver.org/) version string to remove (no confirmation required)\n- a [version constraint](https://opentofu.org/docs/language/expressions/version-constraints) string\n- `all`\n- `but-last` (all versions except the highest installed)\n- `not-used-for:\u003cduration\u003e`, `\u003cduration\u003e` in days or months, like \"14d\" or \"2m\"\n- `not-used-since:\u003cdate\u003e`, `\u003cdate\u003e` format is YYYY-MM-DD, like \"2024-06-30\"\n\n```console\n$ tenv tofu uninstall v1.6.0-alpha4\nUninstallation of OpenTofu 1.6.0-alpha4 successful (directory /home/dvaumoron/.tenv/OpenTofu/1.6.0-alpha4 removed)\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv \u0026lt;tool\u0026gt; list\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nList installed tool versions (located in `TENV_ROOT` directory), sorted in ascending version order.\n\n`tenv \u003ctool\u003e list` has a `--descending`, `-d` flag to sort in descending order.\n\n```console\n$ tenv tofu list -v\n* 1.6.0 (set by /home/dvaumoron/.tenv/OpenTofu/version)\n  1.6.1\nfound 2 OpenTofu version(s) managed by tenv.\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv \u0026lt;tool\u0026gt; list-remote\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nList installable tool versions (from `\u003cTOOL\u003e_REMOTE` url), sorted in ascending version order.\n\n`tenv \u003ctool\u003e list-remote` has a `--descending`, `-d` flag to sort in descending order.\n\n`tenv \u003ctool\u003e list-remote` has a `--stable`, `-s` flag to display only stable version.\n\n```console\n$ tenv tofu list-remote\nFetching all releases information from https://api.github.com/repos/opentofu/opentofu/releases\n1.6.0-alpha1\n1.6.0-alpha2\n1.6.0-alpha3\n1.6.0-alpha4\n1.6.0-alpha5\n1.6.0-beta1\n1.6.0-beta2\n1.6.0-beta3\n1.6.0-beta4\n1.6.0-beta5\n1.6.0-rc1\n1.6.0 (installed)\n1.6.1 (installed)\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv \u0026lt;tool\u0026gt; constraint [expression]\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSet or reset a default constraint expression for the tool.\n\n```console\n$ tenv tf constraint \"\u003c= 1.5.7\"\nWritten \u003c= 1.5.7 in /home/dvaumoron/.tenv/Terraform/constraint\n```\n\nOr without expression :\n\n```console\n$ tenv tg constraint\nRemoved /home/dvaumoron/.tenv/Terragrunt/constraint\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv help [command]\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nHelp about any command.\n\nYou can use `--help` `-h` flag instead.\n\n```console\n$ tenv help tf detect\nDisplay Terraform current version.\n\nUsage:\n  tenv tf detect [flags]\n\nFlags:\n  -a, --arch string          specify arch for binaries downloading (default \"amd64\")\n  -f, --force-remote         force search on versions available at TFENV_REMOTE url\n  -h, --help                 help for detect\n  -k, --key-file string      local path to PGP public key file (replace check against remote one)\n  -n, --no-install           disable installation of missing version\n  -c, --remote-conf string   path to remote configuration file (advanced settings)\n  -u, --remote-url string    remote url to install from\n\nGlobal Flags:\n  -q, --quiet              no unnecessary output (and no log)\n  -r, --root-path string   local path to install versions of OpenTofu, Terraform and Terragrunt (default \"/home/dvaumoron/.tenv\")\n  -v, --verbose            verbose output (and set log level to Trace)\n```\n\n```console\n$ tenv tofu use -h\nSwitch the default OpenTofu version to use (set in TENV_ROOT/OpenTofu/version file)\n\nAvailable parameter options:\n- an exact Semver 2.0.0 version string to use\n- a version constraint expression (checked against version available in TENV_ROOT directory)\n- latest, latest-stable or latest-pre (checked against version available in TENV_ROOT directory)\n- latest-allowed or min-required to scan your OpenTofu files to detect which version is maximally allowed or minimally required.\n\nUsage:\n  tenv tofu use version [flags]\n\nFlags:\n  -a, --arch string           specify arch for binaries downloading (default \"amd64\")\n  -f, --force-remote          force search on versions available at TOFUENV_REMOTE url\n  -t, --github-token string   GitHub token (increases GitHub REST API rate limits)\n  -h, --help                  help for use\n  -k, --key-file string       local path to PGP public key file (replace check against remote one)\n  -n, --no-install            disable installation of missing version\n  -c, --remote-conf string    path to remote configuration file (advanced settings)\n  -u, --remote-url string     remote url to install from\n  -w, --working-dir           create .opentofu-version file in working directory\n\nGlobal Flags:\n  -q, --quiet              no unnecessary output (and no log)\n  -r, --root-path string   local path to install versions of OpenTofu, Terraform and Terragrunt (default \"/home/dvaumoron/.tenv\")\n  -v, --verbose            verbose output (and set log level to Trace)\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv update-path\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nDisplay PATH updated with tenv directory location first. With GITHUB_ACTIONS set to true, write tenv directory location to GITHUB_PATH.\n\nThis 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 \u003ctool\u003e` will indicate different locations). The following shell call should resolve such issues :\n\n```console\nexport PATH=$(tenv update-path)\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etenv version\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nDisplay tenv current version.\n\n```console\n$ tenv version\ntenv version v1.7.0\n```\n\n\n\u003c/details\u003e\n\n\n\u003ca id=\"environment-variables\"\u003e\u003c/a\u003e\n## Environment variables\n\n**tenv** commands support global environment variables and variables by tool for : [OpenTofu](https://opentofu.org), [Terraform](https://www.terraform.io/), [TerraGrunt](https://terragrunt.gruntwork.io/) and [Atmos](https://atmos.tools).\n\n\n\u003ca id=\"tenv-vars\"\u003e\u003c/a\u003e\n### Global tenv environment variables\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_ARCH\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: current tenv binaries architecture)\n\nAllow to override the default architecture for binaries downloading during installation.\n\n`tenv \u003ctool\u003e` subcommands `detect`, `install` and `use` support a `--arch`, `-a`  flag version.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_AUTO_INSTALL\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: false)\n\nIf set to true **tenv** will automatically install missing tool versions needed.\n\n`tenv \u003ctool\u003e` subcommands `detect` and `use` support a `--install`, `-i` enabling flag, and a `--no-install`, `-n` disabling flag.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_FORCE_REMOTE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: false)\n\nIf set to true **tenv** detection of needed version will skip local check and verify compatibility on remote list.\n\n`tenv \u003ctool\u003e` subcommands `detect` and `use` support a `--force-remote`, `-f` flag version.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_GITHUB_TOKEN\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nAllow 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, Terragrunt and Atmos binaries are downloaded from GitHub repository.\n\n`tenv tofu` and `tenv tg` subcommands `detect`, `install`, `list-remote` and `use` support a `--github-token`, `-t` flag version.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_QUIET\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: false)\n\nIf set to true **tenv** disable unnecessary output (including log level forced to off).\n\n`tenv` subcommands support a `--quiet`, `-q` flag version.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_LOG\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"warn\")\n\nSet **tenv** log level (possibilities sorted by decreasing verbosity : \"trace\", \"debug\", \"info\", \"warn\", \"error\", \"off\").\n\n`tenv` support a `--verbose`, `-v` flag which set log level to \"trace\".\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_REMOTE_CONF\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: `${TENV_ROOT}/remote.yaml`)\n\nThe path to a yaml file for [advanced remote configuration](#advanced-remote-configuration) (can be used to call artifact mirror).\n\n`tenv \u003ctool\u003e` subcommands `detect`, `install`, `list-remote` and `use`  support a `--remote-conf`, `-c` flag version.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_ROOT\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: `${HOME}/.tenv`)\n\nThe path to a directory where the local OpenTofu versions, Terraform versions, Terragrunt versions and tenv configuration files exist.\n\n`tenv` support a `--root-path`, `-r` flag version.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_SKIP_LAST_USE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: false)\n\nIf set to true **tenv** disable tracking of last use date for installed versions. It allow to avoid warning message when **tenv** is installed as root user and run with a normal user by skipping the writing of `last-use.txt`. This will lead to misselection with `not-used-for` and `not-used-since` behavior of `tenv uninstall`.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTENV_VALIDATION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: signature)\n\nSet **tenv** validation, known values are \"signature\" (check SHA256 and its signature, see [signature support](#signature-support)), \"sha\" (only check SHA256), \"none\" (no validation).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eGITHUB_ACTIONS\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: false)\n\nIf 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)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eGITHUB_OUTPUT\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nNeeded when GITHUB_ACTIONS is set to true, path to a file to write proxied output.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eGITHUB_PATH\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nUsed by `tenv update-path` when GITHUB_ACTIONS is set to true, path to a file to write tenv directory location.\n\n\u003c/details\u003e\n\n\n\u003ca id=\"tofu-env-vars\"\u003e\u003c/a\u003e\n### OpenTofu environment variables\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_AGNOSTIC_PROXY\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: false)\n\nSwitch `tofu` proxy to an agnostic proxy (behave like `tf`, see [resolution order](#project-binaries)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_ARCH\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSame as TENV_ARCH (compatibility with [tofuenv](https://github.com/tofuutils/tofuenv)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_AUTO_INSTALL\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSame as TENV_AUTO_INSTALL (compatibility with [tofuenv](https://github.com/tofuutils/tofuenv)).\n\n#### Example 1\nUse OpenTofu version 1.6.1 that is not installed, and auto installation stay disabled :\n\n```console\n$ tenv use 1.6.1\nWritten 1.6.1 in /home/dvaumoron/.tenv/OpenTofu/version\n```\n\n#### Example 2\nUse OpenTofu version 1.6.0 that is not installed, and auto installation is enabled :\n\n```console\n$ TOFUENV_AUTO_INSTALL=true tenv tofu use 1.6.0\nInstalling OpenTofu 1.6.0\nFetching release information from https://api.github.com/repos/opentofu/opentofu/releases/tags/v1.6.0\nDownloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_linux_amd64.zip\nDownloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS\nDownloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS.sig\nDownloading https://github.com/opentofu/opentofu/releases/download/v1.6.0/tofu_1.6.0_SHA256SUMS.pem\nInstallation of OpenTofu 1.6.0 successful\nWritten 1.6.0 in /home/dvaumoron/.tenv/OpenTofu/version\n```\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_FORCE_REMOTE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSame as TENV_FORCE_REMOTE.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_INSTALL_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (the default depend on TOFUENV_REMOTE, without change on it, it is \"api\" else it is \"direct\")\n\n- \"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).\n- \"direct\" install mode generate download url of OpenTofu based on TOFUENV_REMOTE.\n- \"mirror\" install mode generate download url with TOFUENV_URL_TEMPLATE (as specified in [TofuDL mirror specification](https://github.com/opentofu/tofudl/blob/mirror-spec/MIRROR-SPECIFICATION.md))\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_LIST_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (the default depend on TOFUENV_LIST_URL, without change on it, it is \"api\" else it is \"html\")\n\n- \"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).\n- \"html\" list mode extract information of OpenTofu releases from parsing an html page at TOFUENV_LIST_URL.\n- \"mirror\" list mode retrieve information of OpenTofu releases at TOFUENV_LIST_URL as [TofuDL Mirroring format](https://get.opentofu.org/tofu/api.json)\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_LIST_URL\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: copy TOFUENV_REMOTE, default is overloaded by \"https://get.opentofu.org/tofu/api.json\" when TOFUENV_LIST_MODE is \"mirror\")\n\nAllow to override the remote url only for the releases listing.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_OPENTOFU_PGP_KEY\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nAllow to specify a local file path or URL to OpenTofu PGP public key. If a URL is provided (starting with \"http://\" or \"https://\"), the key will be downloaded from that URL. If a local file path is provided, the key will be read from that location. If not set, the key will be downloaded from the default URL (https://get.opentofu.org/opentofu.asc).\n\n`tenv tofu` subcommands `detect`, `ìnstall` and `use` support a `--key-file`, `-k` flag version.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_REMOTE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: https://api.github.com/repos/opentofu/opentofu/releases)\n\nURL 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).\n\n`tenv tofu` subcommands `detect`, `install`, `list-remote` and `use` support a `--remote-url`, `-u` flag version.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_REMOTE_PASSWORD\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould 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).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_REMOTE_USER\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould 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).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_ROOT\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSame as TENV_ROOT (compatibility with [tofuenv](https://github.com/tofuutils/tofuenv)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_URL_TEMPLATE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: `https://github.com/opentofu/opentofu/releases/download/v{{ .Version }}/{{ .Artifact }}`)\n\nUsed when TOFUENV_INSTALL_MODE is \"mirror\" (see [TofuDL mirror specification](https://github.com/opentofu/tofudl/blob/mirror-spec/MIRROR-SPECIFICATION.md)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_GITHUB_TOKEN\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSame as TENV_GITHUB_TOKEN (compatibility with [tofuenv](https://github.com/tofuutils/tofuenv)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_TOFU_DEFAULT_CONSTRAINT\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides OpenTofu default constraint, specified in ${TENV_ROOT}/OpenTofu/constraint file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_TOFU_DEFAULT_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides OpenTofu fallback version, specified in ${TENV_ROOT}/OpenTofu/version file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTOFUENV_TOFU_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides OpenTofu version, specified in [`.opentofu-version`](#opentofu-version-files) files.\n\n`tenv tofu` subcommands `install` and `detect` also respects this variable.\n\ne.g. with :\n\n```console\n$ tofu version\nOpenTofu v1.6.1\non linux_amd64\n```\n\nthen :\n\n```console\n$ TOFUENV_TOFU_VERSION=1.6.0 tofu version\nOpenTofu v1.6.0\non linux_amd64\n```\n\n\u003c/details\u003e\n\n\n\u003ca id=\"tf-env-vars\"\u003e\u003c/a\u003e\n### Terraform environment variables\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_AGNOSTIC_PROXY\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: false)\n\nSwitch `terraform` proxy to an agnostic proxy (behave like `tf`, see [resolution order](#project-binaries)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_ARCH\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSame as TENV_ARCH (compatibility with [tfenv](https://github.com/tfutils/tfenv)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_AUTO_INSTALL\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSame as TENV_AUTO_INSTALL (compatibility with [tfenv](https://github.com/tfutils/tfenv)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_FORCE_REMOTE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSame as TENV_FORCE_REMOTE.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_HASHICORP_PGP_KEY\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nAllow to specify a local file path or URL to Hashicorp PGP public key. If a URL is provided (starting with \"http://\" or \"https://\"), the key will be downloaded from that URL. If a local file path is provided, the key will be read from that location. If not set, the key will be downloaded from the default URL (https://www.hashicorp.com/.well-known/pgp-key.txt).\n\n`tenv tf` subcommands `detect`, `ìnstall` and `use` support a `--key-file`, `-k` flag version.\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_INSTALL_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"api\")\n\n- \"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).\n- \"direct\" install mode generate download url of Terraform based on TFENV_REMOTE.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_LIST_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (the default depend on TFENV_LIST_URL, without change on it, it is \"api\" else it is \"html\")\n\n- \"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).\n- \"html\" list mode extract information of Terraform releases from parsing an html page in TFENV_LIST_URL.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_LIST_URL\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: copy TFENV_REMOTE)\n\nAllow to override the remote url only for the releases listing.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_REMOTE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: https://releases.hashicorp.com)\n\nURL 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).\n\n`tenv tf` subcommands `detect`, `install`, `list-remote` and `use` support a `--remote-url`, `-u` flag version.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_REMOTE_PASSWORD\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould 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).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_REMOTE_USER\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould 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).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_ROOT\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nSame as TENV_ROOT (compatibility with [tfenv](https://github.com/tfutils/tfenv)).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_TERRAFORM_DEFAULT_CONSTRAINT\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Terraform default constraint, specified in ${TENV_ROOT}/Terraform/constraint file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_TERRAFORM_DEFAULT_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Terraform fallback version, specified in ${TENV_ROOT}/Terraform/version file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTFENV_TERRAFORM_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Terraform version, specified in [`.terraform-version`](#terraform-version-files) files.\n\n`tenv tf` subcommands `install` and `detect` also respects this variable.\n\ne.g. with :\n\n```console\n$ terraform version\nTerraform v1.7.2\non linux_amd64\n```\n\nthen :\n\n```console\n$ TFENV_TERRAFORM_VERSION=1.7.0 terraform version\nTerraform v1.7.0\non linux_amd64\n\nYour version of Terraform is out of date! The latest version\nis 1.7.2. You can update by downloading from https://www.terraform.io/downloads.html\n```\n\n\u003c/details\u003e\n\n\n\u003ca id=\"tg-env-vars\"\u003e\u003c/a\u003e\n### Terragrunt environment variables\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTG_INSTALL_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (the default depend on TG_REMOTE, without change on it, it is \"api\" else it is \"direct\")\n\n- \"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).\n- \"direct\" install mode generate download url of Terragrunt based on TG_REMOTE.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTG_LIST_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (the default depend on TG_LIST_URL, without change on it, it is \"api\" else it is \"html\")\n\n- \"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).\n- \"html\" list mode extract information of Terragrunt releases from parsing an html page in TG_LIST_URL.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTG_LIST_URL\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: copy TG_REMOTE)\n\nAllow to override the remote url only for the releases listing.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTG_REMOTE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: https://api.github.com/repos/gruntwork-io/terragrunt/releases)\n\nURL 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).\n\n`tenv tg` subcommands `detect`, `install`, `list-remote` and `use` support a `--remote-url`, `-u` flag version.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTG_REMOTE_PASSWORD\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould 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).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTG_REMOTE_USER\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould 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).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTG_DEFAULT_CONSTRAINT\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Terragrunt default constraint, specified in ${TENV_ROOT}/Terragrunt/constraint file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTG_DEFAULT_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Terragrunt fallback version, specified in ${TENV_ROOT}/Terragrunt/version file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTG_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Terragrunt version, specified in [`.terragrunt-version`](#terragrunt-version-files) files.\n\n`tenv tg` subcommands `install` and `detect` also respects this variable.\n\ne.g. with :\n\n```console\n$ terragrunt -v\nterragrunt version v0.55.1\n```\n\nthen :\n\n```console\n$ TG_VERSION=0.54.1 terragrunt -v\nterragrunt version v0.54.1\n```\n\n\u003c/details\u003e\n\n\n\u003ca id=\"tm-env-vars\"\u003e\u003c/a\u003e\n### Terramate environment variables\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTM_INSTALL_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (the default depend on TM_REMOTE, without change on it, it is \"api\" else it is \"direct\")\n\n- \"api\" install mode retrieve download url of Terramate from [Github REST API](https://docs.github.com/en/rest?apiVersion=2022-11-28) (TM_REMOTE must comply with it).\n- \"direct\" install mode generate download url of Terramate based on TM_REMOTE.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTM_LIST_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (the default depend on TM_LIST_URL, without change on it, it is \"api\" else it is \"html\")\n\n- \"api\" list mode retrieve information of Terramate releases from [Github REST API](https://docs.github.com/en/rest?apiVersion=2022-11-28) (TM_LIST_URL must comply with it).\n- \"html\" list mode extract information of Terramate releases from parsing an html page in TM_LIST_URL.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTM_LIST_URL\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: copy TM_REMOTE)\n\nAllow to override the remote url only for the releases listing.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTM_REMOTE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: https://api.github.com/repos/terramate-io/terramate/releases)\n\nURL to install Terramate, when TM_REMOTE differ from its default value, TM_INSTALL_MODE is set to \"direct\" and TM_LIST_MODE is set to \"html\" (assume an artifact proxy usage).\n\n`tenv tm` subcommands `detect`, `install`, `list-remote` and `use` support a `--remote-url`, `-u` flag version.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTM_REMOTE_PASSWORD\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould be used with TM_REMOTE_USER to specify HTTP basic auth when same credential are used with TM_REMOTE and TM_LIST_URL (instead of `https://user:password@host.org` URL format).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTM_REMOTE_USER\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould be used with TM_REMOTE_PASSWORD to specify HTTP basic auth when same credential are used with TM_REMOTE and TM_LIST_URL (instead of `https://user:password@host.org` URL format).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTM_DEFAULT_CONSTRAINT\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Terramate default constraint, specified in ${TENV_ROOT}/Terramate/constraint file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTM_DEFAULT_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Terramate fallback version, specified in ${TENV_ROOT}/Terramate/version file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTM_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Terramate version, specified in [`.terramate-version`](#terramate-version-files) files.\n\n`tenv tm` subcommands `install` and `detect` also respects this variable.\n\ne.g. with :\n\n```console\n$ terramate version\n0.13.0\n```\n\nthen :\n\n```console\n$ TM_VERSION=0.12.0 terramate version\n0.12.0\n```\n\n\u003c/details\u003e\n\n\n\u003ca id=\"atmos-env-vars\"\u003e\u003c/a\u003e\n### Atmos environment variables\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eATMOS_INSTALL_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (the default depend on ATMOS_REMOTE, without change on it, it is \"api\" else it is \"direct\")\n\n- \"api\" install mode retrieve download url of Atmos from [Github REST API](https://docs.github.com/en/rest?apiVersion=2022-11-28) (ATMOS_REMOTE must comply with it).\n- \"direct\" install mode generate download url of Atmos based on ATMOS_REMOTE.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eATMOS_LIST_MODE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (the default depend on ATMOS_LIST_URL, without change on it, it is \"api\" else it is \"html\")\n\n- \"api\" list mode retrieve information of Atmos releases from [Github REST API](https://docs.github.com/en/rest?apiVersion=2022-11-28) (ATMOS_LIST_URL must comply with it).\n- \"html\" list mode extract information of Atmos releases from parsing an html page in ATMOS_LIST_URL.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eATMOS_LIST_URL\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: copy ATMOS_REMOTE)\n\nAllow to override the remote url only for the releases listing.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eATMOS_REMOTE\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: https://api.github.com/repos/cloudposse/atmos/releases)\n\nURL 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).\n\n`tenv atmos` subcommands `detect`, `install`, `list-remote` and `use` support a `--remote-url`, `-u` flag version.\n\nSee [advanced remote configuration](#advanced-remote-configuration) for more details.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eATMOS_REMOTE_PASSWORD\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould 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).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eATMOS_REMOTE_USER\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nCould 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).\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eATMOS_DEFAULT_CONSTRAINT\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Atmos default constraint, specified in ${TENV_ROOT}/Atmos/constraint file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eATMOS_DEFAULT_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Atmos fallback version, specified in ${TENV_ROOT}/Atmos/version file.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eATMOS_VERSION\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nString (Default: \"\")\n\nIf not empty string, this variable overrides Atmos version, specified in [`.atmos-version`](#atmos-version-files) files.\n\n`tenv atmos` subcommands `install` and `detect` also respects this variable.\n\ne.g. with :\n\n```console\n$ atmos version\n👽 Atmos v1.72.0 on linux/amd64\n\n```\n\nthen :\n\n```console\n$ ATMOS_VERSION=1.70 atmos version\n👽 Atmos v1.70.0 on linux/amd64\n```\n\n\u003c/details\u003e\n\n\u003ca id=\"version-files\"\u003e\u003c/a\u003e\n## version files\n\n\u003ca id=\"default-version-file\"\u003e\u003c/a\u003e\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003edefault version file\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThe `TENV_ROOT/\u003cTOOL\u003e/version` file is the tool default version used when no project specific or user specific are found. It can be written with `tenv \u003ctool\u003e use`.\n\n\u003c/details\u003e\n\n\u003ca id=\"opentofu-version-files\"\u003e\u003c/a\u003e\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eopentofu version files\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nIf 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.\nNote, that TOFUENV_TOFU_VERSION can be used to override version specified by `.opentofu-version` file.\n\nRecognize same values as `tenv tofu use` command.\n\nSee [required_version](https://opentofu.org/docs/language/settings#specifying-a-required-opentofu-version) docs.\n\n\u003c/details\u003e\n\n\u003ca id=\"terraform-version-files\"\u003e\u003c/a\u003e\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eterraform version files\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nIf 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.\nNote, that TFENV_TERRAFORM_VERSION can be used to override version specified by those files.\n\nRecognize same values as `tenv tf use` command.\n\nSee [required_version](https://developer.hashicorp.com/terraform/language/settings#specifying-a-required-terraform-version) docs.\n\n\u003c/details\u003e\n\n\u003ca id=\"terragrunt-version-files\"\u003e\u003c/a\u003e\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eterragrunt version files\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nIf 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.\nNote, that TG_VERSION can be used to override version specified by those files.\n\nRecognize same values as `tenv tg use` command.\n\n\u003c/details\u003e\n\n\n\u003ca id=\"terragrunt-hcl-file\"\u003e\u003c/a\u003e\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eterragrunt.hcl or root.hcl file\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n[Terragrunt now recommends](https://terragrunt.gruntwork.io/docs/migrate/migrating-from-root-terragrunt-hcl/) using `root.hcl` instead of `terragrunt.hcl` as the root configuration file name.\n\nIf a `terragrunt.hcl`, `root.hcl`, or their `.json` equivalents exist in the working directory, a parent directory, or the user home directory, **tenv** will read constraints from the `terraform_version_constraint` or `terragrunt_version_constraint` field (depending on proxy or subcommand used).\n\n\nIf both `root.hcl` and `terragrunt.hcl` (or their `.json` versions) are present, `terragrunt.hcl` takes precedence.\n\n\u003c/details\u003e\n\n\u003ca id=\"terramate-version-files\"\u003e\u003c/a\u003e\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eterramate version files\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nIf you put a `.terramate-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.\nNote, that TM_VERSION can be used to override version specified by those files.\n\nRecognize same values as `tenv tm use` command.\n\n\u003c/details\u003e\n\n\u003ca id=\"atmos-version-files\"\u003e\u003c/a\u003e\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eatmos version files\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nIf 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.\nNote, that ATMOS_VERSION can be used to override version specified by those files.\n\nRecognize same values as `tenv atmos use` command.\n\n\u003c/details\u003e\n\n\u003ca id=\"required_version\"\u003e\u003c/a\u003e\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003erequired_version\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nthe `latest-allowed` or `min-required` strategies scan through your IAC files (see list in [project binaries](#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](#project-binaries).\n\nCurrently 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.\n\nexample:\n\n```HCL\nversion = \"\u003e= 1.2.0, \u003c 2.0.0\"\n```\n\nThis would identify the latest version at or above 1.2.0 and below 2.0.0\n\n\u003c/details\u003e\n\n\u003ca id=\"technical-details\"\u003e\u003c/a\u003e\n## Technical details\n\n\u003ca id=\"project-binaries\"\u003e\u003c/a\u003e\n### Project binaries\n\nAll the proxy binaries return the exit code `42` on error happening before proxied command call.\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etofu\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThe `tofu` command in this project is a proxy to OpenTofu's `tofu` command  managed by **tenv**.\n\nThe version resolution order is :\n\n- TOFUENV_TOFU_VERSION environment variable\n- `.opentofu-version` file\n- `.tool-versions` [file](https://asdf-vm.com/manage/configuration.html#tool-versions)\n- `terraform_version_constraint` from `terragrunt.hcl` file\n- `terraform_version_constraint` from `terragrunt.hcl.json` file\n- `terraform_version_constraint` from `root.hcl` file\n- `terraform_version_constraint` from `root.hcl.json` file\n- TOFUENV_TOFU_DEFAULT_VERSION environment variable\n- `${TENV_ROOT}/OpenTofu/version` file (can be written with `tenv tofu use`)\n- `latest-allowed`\n\nThe `latest-allowed` strategy rely on [required_version](#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.\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eterraform\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThe `terraform` command in this project is a proxy to HashiCorp's `terraform` command managed by **tenv**.\n\nThe version resolution order is :\n\n- TFENV_TERRAFORM_VERSION environment variable\n- `.terraform-version` file\n- `.tfswitchrc` file\n- `.tool-versions` [file](https://asdf-vm.com/manage/configuration.html#tool-versions)\n- `terraform_version_constraint` from `terragrunt.hcl` file\n- `terraform_version_constraint` from `terragrunt.hcl.json` file\n- `terraform_version_constraint` from `root.hcl` file\n- `terraform_version_constraint` from `root.hcl.json` file\n- TFENV_TERRAFORM_DEFAULT_VERSION environment variable\n- `${TENV_ROOT}/Terraform/version` file (can be written with `tenv tf use`)\n- `latest-allowed`\n\nThe `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.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eterragrunt\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThe `terragrunt` command in this project is a proxy to Gruntwork's `terragrunt` command managed by **tenv**.\n\nThe version resolution order is :\n\n- TG_VERSION environment variable\n- `.terragrunt-version` file\n- `.tgswitchrc` file\n- `version` from `tgswitch.toml` file\n- `.tool-versions` [file](https://asdf-vm.com/manage/configuration.html#tool-versions)\n- `terragrunt_version_constraint` from `terragrunt.hcl` file\n- `terragrunt_version_constraint` from `terragrunt.hcl.json` file\n- `terragrunt_version_constraint` from `root.hcl` file\n- `terragrunt_version_constraint` from `root.hcl.json` file\n- TG_DEFAULT_VERSION environment variable\n- `${TENV_ROOT}/Terragrunt/version` file (can be written with `tenv tg use`)\n- `latest-allowed`\n\nThe `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`.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eterramate\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThe `terramate` command in this project is a proxy to Terramate's `terramate` command managed by **tenv**.\n\nThe version resolution order is :\n\n- TM_VERSION environment variable\n- `.terramate-version` file\n- TM_DEFAULT_VERSION environment variable\n- `${TENV_ROOT}/Terramate/version` file (can be written with `tenv tm use`)\n- `latest-allowed`\n\nThe `latest-allowed` strategy has no information for Terramate and will fallback to `latest` unless there is default constraint. Adding a default constraint could be done with TM_DEFAULT_CONSTRAINT environment variable or `${TENV_ROOT}/Terramate/constraint` file (can be written with `tenv tm 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`.\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eatmos\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThe `atmos` command in this project is a proxy to Cloudposse's `atmos` command managed by **tenv**.\n\nThe version resolution order is :\n\n- ATMOS_VERSION environment variable\n- `.atmos-version` file\n- `.tool-versions` [file](https://asdf-vm.com/manage/configuration.html#tool-versions)\n- ATMOS_DEFAULT_VERSION environment variable\n- `${TENV_ROOT}/Atmos/version` file (can be written with `tenv atmos use`)\n- `latest-allowed`\n\nThe `latest-allowed` strategy has no information for Atmos and will fallback to `latest`\nunless there is default constraint. Adding a default constraint could be done with\nATMOS_DEFAULT_CONSTRAINT environment variable or `${TENV_ROOT}/Atmos/constraint` file (can\nbe 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`.\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003etf\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThe `tf` command is a proxy to `tofu` or `terraform` depending on the version files present in project.\n\nThe version resolution order is :\n\n- `.opentofu-version` file (launch `tofu`)\n- `tofu` version from `.tool-versions` [file](https://asdf-vm.com/manage/configuration.html#tool-versions)\n- `terraform_version_constraint` from `terragrunt.hcl` file (launch `tofu`)\n- `terraform_version_constraint` from `terragrunt.hcl.json` file (launch `tofu`)\n- `terraform_version_constraint` from `root.hcl` file (launch `tofu`)\n- `terraform_version_constraint` from `root.hcl.json` file (launch `tofu`)\n- `.terraform-version` file (launch `terraform`)\n- `.tfswitchrc` file  (launch `terraform`)\n- `terraform` version from `.tool-versions` [file](https://asdf-vm.com/manage/configuration.html#tool-versions)\n- fail with a message\n\n\u003c/details\u003e\n\n\n\u003ca id=\"advanced-remote-configuration\"\u003e\u003c/a\u003e\n### Advanced remote configuration\n\nThis advanced configuration is meant to call artifact mirror (like [JFrog Artifactory](https://jfrog.com/artifactory)).\n\nThe yaml file from TENV_REMOTE_CONF path can have one part for each supported proxy : `tofu`, `terraform`, `terragrunt` and `atmos`.\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eyaml fields description\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nEach part can have the following string field : `install_mode`, `list_mode`, `list_url`, `url`, `new_base_url`, `old_base_url`, `selector` and `part`\n\nWith `install_mode` set to \"direct\", **tenv** skip the release information fetching and generate download url instead of reading them from API (overridden by `\u003cTOOL\u003e_INSTALL_MODE` env var).\n\nWith `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 `\u003cTOOL\u003e_LIST_MODE` env var).\n\n`url` allows to override the default remote url (overridden by flag or `\u003cTOOL\u003e_REMOTE` env var).\n\n`list_url` allows to override the remote url only for the releases listing (overridden by `\u003cTOOL\u003e_LIST_URL` env var).\n\n`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).\n\nIf `old_base_url` and `new_base_url` are empty, **tenv** try to guess right behaviour based on previous fields.\n\n`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))\n\n\u003c/details\u003e\n\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eExamples\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\nThose examples assume that a GitHub proxy at https://artifactory.example.com/artifactory/github have the same behavior than [JFrog Artifactory](https://jfrog.com/artifactory) :\n\n- 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.\n- 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/\"\n\nExample 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)).\n\n```console\nTFENV_REMOTE=https://artifactory.example.com/artifactory/hashicorp\nTFENV_LIST_MODE=html\n```\n\nExample 2 : Retrieve Terraform binaries from the mirror and list available releases from the Hashicorp releases API.\n\n```console\nTFENV_REMOTE=https://artifactory.example.com/artifactory/hashicorp\nTFENV_LIST_URL=https://releases.hashicorp.com\n```\n\nExample 1 \u0026 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.\n\nExample 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).\n\n```console\nTOFUENV_REMOTE=https://artifactory.example.com/artifactory/github\nTOFUENV_INSTALL_MODE=direct\nTOFUENV_LIST_MODE=html\n```\n\nExample 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\").\n\n```console\nTOFUENV_REMOTE=https://artifactory.example.com/artifactory/github\nTOFUENV_INSTALL_MODE=direct\nTOFUENV_LIST_URL=https://api.github.com/repos/opentofu/opentofu/releases\n```\n\nExample 3 \u0026 4, does not create a rewrite rule (the direct install mode build correct download URLs).\n\nExample 1 \u0026 4 can be merged in a remote.yaml :\n\n```yaml\ntofu:\n  url: \"https://artifactory.example.com/artifactory/github\"\n  install_mode: \"direct\"\n  list_url: \"https://api.github.com/repos/opentofu/opentofu/releases\"\nterraform:\n  url: \"https://artifactory.example.com/artifactory/hashicorp\"\n  list_mode: \"html\"\n```\n\n\u003c/details\u003e\n\n\n\u003ca id=\"lockfile-support\"\u003e\u003c/a\u003e\n### Lockfile support\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eLockfile behavior\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n**tenv** uses lockfiles to ensure safe concurrent operations when multiple instances are run in parallel. This prevents race conditions during installation, uninstallation, and other operations that modify the local version cache.\n\n**Lock file location and naming:**\n- Default location: `${TENV_ROOT}/{tool}.lock` (e.g., `~/.tenv/OpenTofu.lock`)\n- Can be customized using the `TENV_LOCK_PATH` environment variable\n- Each tool (OpenTofu, Terraform, Terragrunt, Terramate, Atmos) uses its own lock file\n\n**Parallel execution behavior:**\nWhen multiple **tenv** instances attempt to run simultaneously:\n\n1. The first instance creates its lock file successfully and proceeds with the operation\n2. Subsequent instances fail to create the lock file (due to exclusive creation) and enter a retry loop\n3. The retry mechanism waits 1 second between attempts and logs a warning message\n4. Once the first instance completes and releases its lock, the next waiting instance can acquire the lock and proceed\n\n**Example retry behavior:**\n```console\n$ tenv tofu install 1.6.0 \u0026 tenv tofu install 1.6.1\n[1] Installing OpenTofu 1.6.0\n[2] can not write .lock file, will retry: file already exists\n[2] can not write .lock file, will retry: file already exists\n[1] Installation of OpenTofu 1.6.0 successful\n[2] Installing OpenTofu 1.6.1\n[2] Installation of OpenTofu 1.6.1 successful\n```\n\n**Lock scope:**\n- **Operations that modify versions** (`install`, `uninstall`) use locks to prevent conflicts\n- **Read-only operations** (`list`, `list-remote`, `detect`) don't need locks\n- **Batch operations** (`InstallMultiple` API) use a single lock for the entire batch\n- Locks are automatically cleaned up when operations finish (success or failure)\n- Interrupt signals (Ctrl+C) properly release locks to prevent deadlocks\n\n\u003c/details\u003e\n\n\u003ca id=\"signature-support\"\u003e\u003c/a\u003e\n### Signature support\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eOpenTofu signature support\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n**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).\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTerraform signature support\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n**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).\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eTerragrunt signature support\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n**tenv** checks the sha256 checksum (there is no signature available).\n\n\u003c/details\u003e\n\n\u003cdetails markdown=\"1\"\u003e\u003csummary\u003e\u003cb\u003eAtmos signature support\u003c/b\u003e\u003c/summary\u003e\u003cbr\u003e\n\n**tenv** checks the sha256 checksum (there is no signature available).\n\n\u003c/details\u003e\n\n\u003ca id=\"verifying-signature\"\u003e\u003c/a\u003e\n## Verifying tenv Signatures\n\nYou 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.\n\n\u003e [!NOTE]\n\u003e 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.\n\n```bash\n# Get latest release\nLATEST_VERSION=$(curl --silent https://api.github.com/repos/tofuutils/tenv/releases/latest | jq -r .tag_name) #v2.6.1\n\n# Get checksum files\ncurl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_checksums.txt\ncurl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_checksums.txt.sig\ncurl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_checksums.txt.pem\n\n# Get RPM files\ncurl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_amd64.rpm\ncurl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_amd64.rpm.sig\ncurl --silent -OL https://github.com/tofuutils/tenv/releases/download/${LATEST_VERSION}/tenv_${LATEST_VERSION}_amd64.rpm.pem\n\n# Verify signatures\ncosign \\\n    verify-blob \\\n    --certificate-identity \"https://github.com/tofuutils/tenv/.github/workflows/release.yml@refs/tags/${LATEST_VERSION}\" \\\n    --signature \"tenv_${LATEST_VERSION}_checksums.txt.sig\" \\\n    --certificate \"tenv_${LATEST_VERSION}_checksums.txt.pem\" \\\n    --certificate-oidc-issuer \"https://token.actions.githubusercontent.com\" \\\n    \"tenv_${LATEST_VERSION}_checksums.txt\"\n\nTENV_SIG_CHECK=$?\n\ncosign \\\n    verify-blob \\\n    --certificate-identity \"https://github.com/tofuutils/tenv/.github/workflows/release.yml@refs/tags/${LATEST_VERSION}\" \\\n    --signature \"tenv_${LATEST_VERSION}_amd64.rpm.sig\" \\\n    --certificate \"tenv_${LATEST_VERSION}_amd64.rpm.pem\" \\\n    --certificate-oidc-issuer \"https://token.actions.githubusercontent.com\" \\\n    \"tenv_${LATEST_VERSION}_amd64.rpm\"\n\nTENV_ASSET_CHECK=$?\n\n# Check everything is good before installation\nif [ \"$TENV_SIG_CHECK\" -eq \"0\" ] \u0026\u0026 [ \"$TENV_ASSET_CHECK\" -eq \"0\" ] \u0026\u0026 shasum -a 256 -c \"tenv_${LATEST_VERSION}_checksums.txt\" --ignore-missing\nthen\n  dnf install \"tenv_${LATEST_VERSION}_amd64.rpm\" -y\n  tenv --version\nelse\n  echo \"Signature verification and/or checksum checks failed!\"\nfi\n```\n\n\u003ca id=\"contributing\"\u003e\u003c/a\u003e\n## Contributing\n\nContributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\nCheck out our [contributing guide](CONTRIBUTING.md) to get started.\n\nDon't forget to give the project a star! Thanks again!\n\n\u003ca id=\"community\"\u003e\u003c/a\u003e\n## Community\nHave questions or suggestions? Reach out to us via:\n\n* [GitHub Issues](LINK_TO_ISSUES)\n* User/Developer Group: Join github community to get update of Harbor's news, features, releases, or to provide suggestion and feedback.\n* Slack: Join tofuutils's community for discussion and ask questions: OpenTofu, channel: #tofuutils\n\n\n\u003ca id=\"authors\"\u003e\u003c/a\u003e\n## Authors\ntenv 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:\n\n\u003c!-- markdownlint-disable no-inline-html --\u003e\n\u003ca href=\"https://github.com/tofuutils/tenv/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=tofuutils/tenv\" /\u003e\n\u003c/a\u003e\n\n\n\u003ca href=\"https://star-history.com/#tofuutils/tenv\u0026Date\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/svg?repos=tofuutils/tenv\u0026type=Date\u0026theme=dark\" /\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/svg?repos=tofuutils/tenv\u0026type=Date\" /\u003e\n    \u003cimg alt=\"Star History Chart\" src=\"https://api.star-history.com/svg?repos=tofuutils/pre-commit-opentofu\u0026type=Date\" /\u003e\n  \u003c/picture\u003e\n\u003c/a\u003e\n\n\u003c!-- markdownlint-enable no-inline-html --\u003e\n\n\u003ca id=\"licence\"\u003e\u003c/a\u003e\n## LICENSE\nThe tenv project is distributed under the Apache 2.0 license. See [LICENSE](LICENSE).\n","funding_links":[],"categories":["Productivity Tools","Tools","Go","Continuous Delivery \u0026 GitOps","Version Managers"],"sub_categories":["Environment managers","Community providers","OpenTofu"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftofuutils%2Ftenv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftofuutils%2Ftenv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftofuutils%2Ftenv/lists"}