Skip to main content

Tool Version Manager (ASDF)

Many times we need to use different versions of terraform, kubectl, vagrant, etc. What could we do to have multiple binaries with different versions available?

Let's take the terraform binary as an example. We can have multiple terraform binaries.

  • terraform-1.2
  • terraform-1.3
  • terraform-1.4
  • ....

We can create a symbolic link terraform that will point to one of them. However, we have to keep changing where the symbolic link points.

The most interesting way I found to solve this problem was using a tool versioner.

asdf does this easily and allows us many other conveniences.

To install terraform or kubectl, whatever the binary, we need to add the repository, add the repository key, update the package manager, and then install.

Every time we need to install some tool we have to go to its documentation and follow the process. A pain in the neck...

asdf installs everything for you, in the version you want and with the right to keep switching versions without much effort.

It's still possible to define the version per project and much more. Let's check it out.

Installation

The requirements are only git and curl.

As the asdf installation is very well documented, it's not worth reinventing the wheel.

Basically it's cloning the project, configuring it in the system path and enabling completion to improve interaction with the cli.

git clone https://github.com/asdf-vm/asdf.git ~/.asdf

Just follow the documentation for your type of environment.

With everything ready we can check out a bit of the tool.

# Completion working
❯ asdf <tab>
current -- display current versions for named package (else all)
env -- prints or runs an executable under a command environment
exec -- executes the command shim for the current version
global -- set package global version
info -- print os, shell and asdf debug information
install -- install plugin at stated version, or all from .tools-versions
latest -- display latest version available to install for a named package
list -- list installed versions of a package
list-all -- list all available (remote) versions of a package
local -- set package local version
plugin -- plugin management sub-commands
plugin-add -- add plugin from asdf-plugins repo or from git URL
plugin-list -- list installed plugins (--urls with URLs)
plugin-list-all -- list all plugins registered in asdf-plugins repo
plugin-remove -- remove named plugin and all packages for it
plugin-update -- update named plugin (or --all)
reshim -- recreate shims for version of a package
shell -- via env vars, set package to version in current shell
shim -- shim management sub-commands
shim-versions -- list for given command which plugins and versions provide it
uninstall -- remove a specific version of a package
update -- update ASDF to the latest stable release (unless --head)
where -- display install path for given package at optional specified version
which -- display path to an executable

❯ asdf version
v0.14.0

Plugins

Each plugin is responsible for some project, usually runtimes and tools.

To get an idea of what's available, run the command below.

> asdf plugin-list-all

❯ asdf plugin-list-all
updating plugin repository...HEAD is now at 8e311ee feat: add dynatrace-monaco plugin (#951)
...
# The list is huge

Let's install terraform then.

❯ asdf plugin-add terraform
Plugin named terraform added

# Installing the latest version
# Not all have latest, most projects have the latest tag. Sometimes it's necessary to pass the specific version.
❯ asdf install terraform latest

# Let's see what we have using completion after terraform

❯ asdf install terraform <tab>
0.1.0 0.11.8 0.12.29 0.14.2 0.5.0 0.7.8 1.0.7 1.2.1 1.4.0-rc1 1.6.3
0.1.1 0.11.9 0.12.3 0.14.3 0.5.1 0.7.9 1.0.8 1.2.2 1.4.1 1.6.4
0.10.0 0.11.9-beta1 0.12.30 0.14.4 0.5.3 0.8.0 1.0.9 1.2.3 1.4.2 1.6.5
0.10.0-beta1 0.12.0 0.12.31 0.14.5 0.6.0 0.8.1 1.1.0 1.2.4 1.4.3 1.6.6
0.10.0-beta2 0.12.0-alpha1 0.12.4 0.14.6 0.6.1 0.8.2 1.1.0-alpha20210616 1.2.5 1.4.4 1.7.0
0.10.0-rc1 0.12.0-alpha2 0.12.5 0.14.7 0.6.10 0.8.3 1.1.0-alpha20210630 1.2.6 1.4.5 1.7.0-alpha20231025
0.10.1 0.12.0-alpha3 0.12.6 0.14.8 0.6.11 0.8.4 1.1.0-alpha20210714 1.2.7 1.4.6 1.7.0-alpha20231108
0.10.2 0.12.0-alpha4 0.12.7 0.14.9 0.6.12 0.8.5 1.1.0-alpha20210728 1.2.8 1.4.7 1.7.0-alpha20231130
0.10.3 0.12.0-beta1 0.12.8 0.15.0 0.6.13 0.8.6 1.1.0-alpha20210811 1.2.9 1.5.0 1.7.0-beta1
0.10.4 0.12.0-beta2 0.12.9 0.15.0-alpha20210107 0.6.14 0.8.7 1.1.0-alpha20210908 1.3.0 1.5.0-alpha20230405 1.7.0-beta2
0.10.5 0.12.0-rc1 0.13.0 0.15.0-alpha20210127 0.6.15 0.8.8 1.1.0-alpha20210922 1.3.0-alpha20220608 1.5.0-alpha20230504 1.7.0-rc1
0.10.6 0.12.1 0.13.0-beta1 0.15.0-alpha20210210 0.6.16 0.9.0 1.1.0-alpha20211006 1.3.0-alpha20220622 1.5.0-beta1 1.7.0-rc2
0.10.7 0.12.10 0.13.0-beta2 0.15.0-beta1 0.6.2 0.9.1 1.1.0-alpha20211020 1.3.0-alpha20220706 1.5.0-beta2 1.7.1
0.10.8 0.12.11 0.13.0-beta3 0.15.0-beta2 0.6.3 0.9.10 1.1.0-alpha20211029 1.3.0-alpha20220803 1.5.0-rc1 1.7.2
0.11.0 0.12.12 0.13.0-rc1 0.15.0-rc1 0.6.4 0.9.11 1.1.0-beta1 1.3.0-alpha20220817 1.5.0-rc2 1.7.3
0.11.0-beta1 0.12.13 0.13.1 0.15.0-rc2 0.6.5 0.9.2 1.1.0-beta2 1.3.0-beta1 1.5.1 1.7.4
0.11.0-rc1 0.12.14 0.13.2 0.15.1 0.6.6 0.9.3 1.1.0-rc1 1.3.0-rc1 1.5.2 1.7.5
0.11.1 0.12.15 0.13.3 0.15.2 0.6.7 0.9.4 1.1.1 1.3.1 1.5.3 1.8.0
0.11.10 0.12.16 0.13.4 0.15.3 0.6.8 0.9.5 1.1.2 1.3.10 1.5.4 1.8.0-alpha20240131
0.11.11 0.12.17 0.13.5 0.15.4 0.6.9 0.9.6 1.1.3 1.3.2 1.5.5 1.8.0-alpha20240214
0.11.12 0.12.18 0.13.6 0.15.5 0.7.0 0.9.7 1.1.4 1.3.3 1.5.6 1.8.0-alpha20240216
0.11.12-beta1 0.12.19 0.13.7 0.2.0 0.7.1 0.9.8 1.1.5 1.3.4 1.5.7 1.8.0-alpha20240228
0.11.13 0.12.2 0.14.0 0.2.1 0.7.10 0.9.9 1.1.6 1.3.5 1.6.0 1.8.0-beta1
0.11.14 0.12.20 0.14.0-alpha20200910 0.2.2 0.7.11 1.0.0 1.1.7 1.3.6 1.6.0-alpha20230719 1.8.0-rc1
0.11.15 0.12.21 0.14.0-alpha20200923 0.3.0 0.7.12 1.0.1 1.1.8 1.3.7 1.6.0-alpha20230802 1.8.0-rc2
0.11.15-oci 0.12.22 0.14.0-alpha20201007 0.3.1 0.7.13 1.0.10 1.1.9 1.3.8 1.6.0-alpha20230816 1.8.1
0.11.2 0.12.23 0.14.0-beta1 0.3.5 0.7.2 1.0.11 1.2.0 1.3.9 1.6.0-beta1 1.9.0-alpha20240404
0.11.3 0.12.24 0.14.0-beta2 0.3.6 0.7.3 1.0.2 1.2.0-alpha-20220328 1.4.0 1.6.0-beta2 latest
0.11.4 0.12.25 0.14.0-rc1 0.3.7 0.7.4 1.0.3 1.2.0-alpha20220413 1.4.0-alpha20221109 1.6.0-beta3 latest:
0.11.5 0.12.26 0.14.1 0.4.0 0.7.5 1.0.4 1.2.0-beta1 1.4.0-alpha20221207 1.6.0-rc1
0.11.6 0.12.27 0.14.10 0.4.1 0.7.6 1.0.5 1.2.0-rc1 1.4.0-beta1 1.6.1
0.11.7 0.12.28 0.14.11 0.4.2 0.7.7 1.0.6 1.2.0-rc2 1.4.0-beta2 1.6.2

# Let's install version 1.7.5 as a specific version.
❯ asdf install terraform 1.7.5

# We already have two terraform versions, now let's set one of them to be global.

# Using completion will show us all available that are already installed.
❯ asdf global terraform <tab>
1.7.5 1.8.1 system

asdf global terraform 1.8.1

❯ terraform version
Terraform v1.8.1
on darwin_arm64

# Let's change to version 1.7.5
❯ asdf global terraform 1.7.5
❯ terraform version
Terraform v1.7.5
on darwin_arm64

Your version of Terraform is out of date! The latest version
is 1.8.1. You can update by downloading from https://www.terraform.io/downloads.html

To check everything that's installed on the system between plugins and versions we can use the list command.

❯ asdf list
terraform
*1.7.5
1.8.1
trivy
*0.50.1

Version per Project

We have two projects, A and B and we're going to put in the .tools-versions file the correct version of what we need in this project.

mkdir A B

echo "terraform 1.8.1" > A/.tools-versions
echo "terraform 1.7.5" > B/.tools-versions

Remembering that we already have the terraform versions in our system. Before let's check the terraform version that's defined as global.

❯ terraform version
Terraform v1.8.1
on darwin_arm64

In A let's test the terraform version. We wouldn't need this, because if there's no version defined, the global is what prevails.

cd A

❯ terraform version
Terraform v1.8.1
on darwin_arm64

# Same as global as expected

Now in B...

cd B

❯ terraform version
Terraform v1.7.5
on darwin_arm64

Your version of Terraform is out of date! The latest version
is 1.8.1. You can update by downloading from https://www.terraform.io/downloads.html

I just thank the maintainers of this project that makes our life so much easier!