tenv

repository·main·Indexed 23 days ago

https://github.com/tofuutils/tenv

A Go-based version manager optimized for the HashiCorp/OpenTofu ecosystem, supporting OpenTofu, Terraform, Terragrunt, Terramate, and Atmos. It provides a high-performance, cross-platform alternative to generic version managers with features including Semver 2.0.0 compatibility, HCL parsing for version constraints, and signature verification via cosign and PGP.

Tokens
11.6K
Snippets
18
Records
63
Agent score
79%

What's inside tenv

  1. Overview of tenv

    main

    tenv is a versatile version manager written in Go designed for managing multiple versions of the following tools:

    • OpenTofu
    • Terraform
    • Terragrunt
    • Terramate
    • Atmos

    It is a successor to tofuenv and tfenv. Key features include:

    • Semver 2.0.0 Compatibility: Uses go-version for semantic versioning and an HCL parser to extract version constraints from configuration files.
    • Signature Verification: Supports cosign (if installed) and PGP (via gopenpgp) for secure downloads.
    • High Performance & Portability: Distributed as independent binaries with support for Linux, MacOS, Windows, BSD, and Solaris.
    • Compatibility: Maintains command syntax compatibility with tfenv and tofuenv in nearly all cases.
  2. Manage supported IaC tools with tenv

    main

    tenv manages multiple Infrastructure as Code (IaC) tools using a consistent CLI interface. You can manage each tool using the pattern tenv <tool> <command>.

    Supported tools and their aliases:

    • OpenTofu: tofu or opentofu (Env var: TOFUENV_)
    • Terraform: tf or terraform (Env var: TFENV_)
    • Terragrunt: tg or terragrunt (Env var: TG_)
    • Terramate: tm or terramate (Env var: TM_)
    • Atmos: at or atmos (Env var: ATMOS_)

    If you run tenv without a subcommand, it displays an interactive menu to manage tools and their versions.

    tenv <tool> <command>
  3. Version resolution order for Terramate (terramate)

    main

    When using the terramate proxy command, tenv resolves the version to use based on the following priority order:

    1. TM_VERSION environment variable
    2. .terramate-version file
    3. TM_DEFAULT_VERSION environment variable
    4. ${TENV_ROOT}/Terramate/version file (set via tenv tm use)
    5. latest-allowed strategy

    The latest-allowed strategy: Falls back to latest unless a default constraint is provided via TM_DEFAULT_CONSTRAINT environment variable or the ${TENV_ROOT}/Terramate/constraint file (set via tenv tm constraint).

  4. Set a tool's default version with TENV_ROOT

    main

    You can define a global default version for a tool by creating a version file at TENV_ROOT/<TOOL>/version. This version is used when no project-specific or user-specific version files are detected. You can also set this version using the command:

    tenv <tool> use

  5. Version resolution order for Terraform (terraform)

    main

    When using the terraform proxy command, tenv resolves the version to use based on the following priority order:

    1. TFENV_TERRAFORM_VERSION environment variable
    2. .terraform-version file
    3. .tfswitchrc file
    4. .tool-versions file
    5. terraform_version_constraint from terragrunt.hcl or terragrunt.hcl.json
    6. terraform_version_constraint from root.hcl or root.hcl.json
    7. TFENV_TERRAFORM_DEFAULT_VERSION environment variable
    8. ${TENV_ROOT}/Terraform/version file (set via tenv tf use)
    9. latest-allowed strategy

    The latest-allowed strategy: Relies on required_version from .tf or .tf.json files. If no constraint is found, it falls back to latest. You can define a default constraint using the TFENV_TERRAFORM_DEFAULT_CONSTRAINT environment variable or the ${TENV_ROOT}/Terraform/constraint file (set via tenv tf constraint).

  6. Read Terragrunt constraints from HCL files

    main

    tenv can read version constraints directly from Terragrunt configuration files (terragrunt.hcl, root.hcl, or their .json equivalents) found in the working directory, a parent directory, or the user home directory.

    It looks for the following fields:

    • terraform_version_constraint
    • terragrunt_version_constraint

    Precedence: If both root.hcl and terragrunt.hcl (or their .json versions) are present, terragrunt.hcl takes precedence.

  7. Version resolution order for OpenTofu (tofu)

    main

    When using the tofu proxy command, tenv resolves the version to use based on the following priority order:

    1. TOFUENV_TOFU_VERSION environment variable
    2. .opentofu-version file
    3. .tool-versions file
    4. terraform_version_constraint from terragrunt.hcl or terragrunt.hcl.json
    5. terraform_version_constraint from root.hcl or root.hcl.json
    6. TOFUENV_TOFU_DEFAULT_VERSION environment variable
    7. ${TENV_ROOT}/OpenTofu/version file (set via tenv tofu use)
    8. latest-allowed strategy

    The latest-allowed strategy: Relies on required_version from .tofu, .tofu.json, .tf, or .tf.json files. If no constraint is found, it falls back to latest. You can define a default constraint using the TOFUENV_TOFU_DEFAULT_CONSTRAINT environment variable or the ${TENV_ROOT}/OpenTofu/constraint file (set via tenv tofu constraint).

  8. Use lockfiles for safe concurrent operations

    main

    tenv uses lockfiles to prevent race conditions during installation, uninstallation, or other operations that modify the local version cache when multiple instances are running in parallel.

    • Default location: ${TENV_ROOT}/{tool}.lock (e.g., ~/.tenv/OpenTofu.lock).
    • Customization: Use the TENV_LOCK_PATH environment variable.
    • Behavior: If an instance cannot acquire a lock, it enters a retry loop, waiting 1 second between attempts and logging a warning.
    • Scope: Locks are used for operations that modify versions (install, uninstall). Read-only operations (list, list-remote, detect) do not require locks.

    Example of retry behavior:

    $ tenv tofu install 1.6.0 & tenv tofu install 1.6.1
    [1] Installing OpenTofu 1.6.0
    [2] can not write .lock file, will retry: file already exists
    [2] can not write .lock file, will retry: file exists
    [1] Installation of OpenTofu 1.6.0 successful
    [2] Installing OpenTofu 1.6.1
    [2] Installation of OpenTofu 1.6.1 successful
  9. tenv vs asdf-vm

    main

    While both tenv and asdf-vm aim to simplify tool version management, tenv offers several specific advantages for DevOps workflows:

    Featuretenvasdf-vm
    SpecializationDedicated features for OpenTofu, Terraform, Terragrunt, Terramate, and Atmos (e.g., HCL parsing)Generic and plugin-based
    DependenciesIndependent binaries; no reliance on shell or other CLI executablesRelies on shell/plugins
    Platform SupportLinux, MacOS, Windows, BSD, and SolarisNatively supports Linux and MacOS
    SecurityChecks sha256 checksums and signatures via cosignNot a primary focus
    PerformanceOptimized for specific toolsGeneral purpose
  10. Version resolution order for Terragrunt (terragrunt)

    main

    When using the terragrunt proxy command, tenv resolves the version to use based on the following priority order:

    1. TG_VERSION environment variable
    2. .terragrunt-version file
    3. .tgswitchrc file
    4. version from tgswitch.toml file
    5. .tool-versions file
    6. terragrunt_version_constraint from terragrunt.hcl or terragrunt.hcl.json
    7. terragrunt_version_constraint from root.hcl or root.hcl.json
    8. TG_DEFAULT_VERSION environment variable
    9. ${TENV_ROOT}/Terragrunt/version file (set via tenv tg use)
    10. latest-allowed strategy

    The latest-allowed strategy: Falls back to latest unless a default constraint is provided via TG_DEFAULT_CONSTRAINT environment variable or the ${TENV_ROOT}/Terragrunt/constraint file (set via tenv tg constraint).

  11. Understand version constraint strategies

    main

    The latest-allowed or min-required strategies scan IaC files to identify a version conforming to a specific constraint. If no IaC files or default constraints are found, they fallback to latest.

    Constraints follow the standard Terraform/OpenTofu format. For example, a constraint like version = ">= 1.2.0, < 2.0.0" will identify the latest version that is at or above 1.2.0 and below 2.0.0.

    version = ">= 1.2.0, < 2.0.0"
  12. Version resolution order for the `tf` proxy command

    main

    The tf command is a smart proxy that decides whether to launch tofu or terraform based on the presence of version files in the project:

    1. .opentofu-version file $\rightarrow$ launches tofu
    2. tofu version from .tool-versions $\rightarrow$ launches tofu
    3. terraform_version_constraint from terragrunt.hcl or terragrunt.hcl.json $\rightarrow$ launches tofu
    4. terraform_version_constraint from root.hcl or root.hcl.json $\rightarrow$ launches tofu
    5. .terraform-version file $\rightarrow$ launches terraform
    6. .tfswitchrc file $\rightarrow$ launches terraform
    7. terraform version from .tool-versions $\rightarrow$ launches terraform

    If none of these match, the command fails with an error message.