Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Terve πŸ‘‹

Release License OS

⚠️ This tool is deprecated and is no longer maintained. Use e.g. asdf or tfenv + tgenv instead.

Unified, minimal terraform and terragrunt version manager.


  • Minimal by design: no shims, no magic, quiet, but extendable thru scripting
  • SHA256 checksums are checked for terraform and terragrunt binary downloads
  • PGP signatures are checked for terraform binary downloads (if Hashicorp's public key is configured)

Supported platforms

  • Linux (amd64, arm64)
    • NOTE: only terraform 0.11.15, 0.12.{30,31}, 0.13.5+ and terragrunt 0.28.12+ ship linux arm64 binaries
  • macOS (amd64, arm64)
    • NOTE: only terraform 1.1.0+ and terragrunt 0.28.12+ ship macOS arm64 binaries
  • Windows (amd64)

⚠️ A pre-built terve binary is not yet available for macOS arm64, because Apple M1-based GitHub runners are not yet available, see this issue


  1. Download terve for your platform, check file integrity, and install the binary somewhere in your PATH, e.g. /usr/local/bin/terve
    • On Linux/macOS, file integrity can be checked in the directory where you downloaded the binary and SHA256SUMS, like so:

       $ ls
       SHA256SUMS terve_linux_amd64
       $ sha256sum -c --ignore-missing 2>/dev/null SHA256SUMS
       terve_linux_amd64: OK
    • On Linux/macOS, be sure to make the binary executable: chmod +x terve

  2. Create the ~/.terve directory tree by running terve --bootstrap
  3. Add the ~/.terve/bin directory to PATH (using e.g. .bashrc or Windows' control panel)
  4. Copy Hashicorp's PGP public key in ~/.terve/etc/terraform.asc (read-only, mode 0444 on Linux/macOS)
    • This public key is used to verify terraform binary download PGP signatures
    • If not installed (or bad file permissions), terve will log a warning for terraform installs
  5. Install your desired versions of terraform and terragrunt
  6. Select your desired versions of terraform and terragrunt

How it works

Terve uses hard links to configure selected terraform/terragrunt binary versions.

All files are kept in directory ~/.terve like so (example directory tree for Linux):

β”œβ”€β”€ bin
β”‚Β Β  β”œβ”€β”€ terraform
β”‚Β Β  └── terragrunt
β”œβ”€β”€ etc
β”‚Β Β  └── terraform.asc
β”œβ”€β”€ opt
β”‚Β Β  β”œβ”€β”€ terraform
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 0.1.0
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1.0.2
β”‚Β Β  β”‚Β Β  └── 1.0.3
β”‚Β Β  └── terragrunt
β”‚Β Β      β”œβ”€β”€ 0.0.4
β”‚Β Β      β”œβ”€β”€ 0.1.0
β”‚Β Β      └── 0.31.2
└── var
    β”œβ”€β”€ terraform
    β”‚Β Β  └── version
    └── terragrunt
        └── version
  • bin – selected terraform and terragrunt binaries (hard-linked to files in opt)
  • etc – configuration
  • opt – installed terraform and terragrunt binaries, version is encoded in file name
  • var – variable data, currently only holders for selected version strings


Managed <binary> is tf (long form: terraform) or tg (long form: terragrunt).

Install, select and remove are idempotent, and can be run multiple times for a version without error.


Lists installed or available (remote) versions, sorted latest first.

Syntax: terve l[ist] <binary> [spec] where spec is r[emote]

  • terve l tf lists installed (local) terraform versions
  • terve l tf r lists available (remote) terraform versions
  • terve l tf r | tac lists available terraform versions, sorted oldest first
  • terve l tg r | grep 0.29. lists available terragrunt 0.29.x versions

πŸ’‘ List remote does not return pre-release versions (e.g. terraform 0.15.0-rc2), but such versions can be installed/selected/removed (for testing).


Installs a specific version.

Syntax: terve i[nstall] <binary> <semver>

  • terve i tf 0.12.31 installs terraform version 0.12.31
  • terve i tf "$(terve l tf r | head -n1)" installs latest version of terraform
  • terve i tf "$(cat .terraform-version)" installs terraform version defined in .terraform-version
  • terve i tg "$(cat .terragrunt-version)" installs terragrunt version defined in .terragrunt-version
  • terve l tg r | grep 0.29. | xargs -n1 -P4 terve i tg installs all available terragrunt 0.29.x versions

⚠️ terragrunt releases < 0.18.1 do not ship SHA256SUMS files, so their file integrity cannot be checked


Selects an installed version for use.

Syntax: terve s[elect] <binary> <semver>

  • terve s tf 0.12.31 selects terraform version 0.12.31
  • terve s tf "$(cat .terraform-version)" selects terraform version defined in .terraform-version


Removes an installed version.

Syntax: terve r[emove] <binary> <semver>

  • terve r tf 0.12.31 removes terraform version 0.12.31
  • terve l tf | grep 0.11. | xargs -n1 terve r tf removes all installed terraform 0.11.x versions

πŸ’‘ Removing a version does not reset current selection


Tells which version is currently selected.

Syntax: terve w[hich] <binary>

$ terve w tf

Optional shell extensions

Terraform switch (Linux and macOS)

Simple switch to specified terraform version.

function tfv {
  local version="$1"
  if [ -z "$version" ]; then
    echo "Usage: tfv <version>, e.g. tfv 1.2.3"
    return 1
  terve i tf "$version" >/dev/null && \
  terve s tf "$version" >/dev/null && \
  echo "Switched to terraform $version"

Terra(form|grunt) use (Linux and macOS)

Use terraform and terragrunt versions defined in .terraform-version and .terragrunt-version (in current working directory or any parent directory)


upcat() {
    while [ "$PWD" != "/" ]; do
        if [ -r "$file" ]; then
            cat "$file"
        cd ..

tf_version="$(upcat .terraform-version)"
tg_version="$(upcat .terragrunt-version)"

if [ -z "$tf_version" ]; then
    echo "ERROR: No .terraform-version file found"
    exit 1

if [ -z "$tg_version" ]; then
    echo "ERROR: No .terragrunt-version file found"
    exit 2

terve i tf "$tf_version" && terve s tf "$tf_version"
terve i tg "$tg_version" && terve s tg "$tg_version"


You need cargo (Rust's build tool). To run all tests, run cargo test.

Visual Studio Code with rust-analyzer provides a good IDE experience.

To build a release binary, run cargo build --release. Binary is then found in target/release/.