Tool Version Manager
Published: 2022-09-20 21:08:17

##Tool Version Manager

Asdf is a tool version manager where all the tools and the versions are defined in a single file (.tool-versions). This single file can be shared across multiple teams to ensure everyone uses same versions of the same tool(s).

Source: [asdf introduction page](https://asdf-vm.com/guide/introduction.html)

**Reader’s Guide**

This technical documentation focus on Software Developers, DevOps, Cloud, SRE, System Engineers and Native Engineers that uses many tools.

- [Before Tool Version Manager](https://www.notion.so/Tool-Version-Manager-e8280abe22094d219853ee02bf075e40)
- [Cons of Legacy Tools-Configurations](https://www.notion.so/Tool-Version-Manager-e8280abe22094d219853ee02bf075e40)
- [How Asdf works](https://www.notion.so/Tool-Version-Manager-e8280abe22094d219853ee02bf075e40)
- [Asdf Setups](https://www.notion.so/Tool-Version-Manager-e8280abe22094d219853ee02bf075e40)

###Before Tool Version Manager

The traditional method for multiple versions for a tool require various configurations which are also specific to tool and dependent on libraries. For an example, Let’s look at python on Mac.

install python with Homebrew 

`brew install python`

```bash
python --version
```

> *This command will display the active python version*
> 

```bash
ls -l /usr/local/bin/python*
```

> *This command will display all the installed python versions*
> 

```bash
ln -s -f /usr/local/bin/python3.8.1 /usr/local/bin/python
```

> *This symlink command will change the active python version to python3.8.1*
> 

This setup is a global wide configuration-That is-this configuration is not project specific. To be project specific will require performing the last two steps again and again as this case may require. And, indeed, this is a punishment 😢

I’m a DevOps Engineer and I constantly work with many tools. From my experience over the years working for different companies and Crypto Fintech, I can tell you how painful this can be. 

> **Imagine multiple clusters of different versions in different environments(Dev, Stage, Prod, QA…). Accessing these clusters where the client tool `kubectl` requires different version. Another tool to consider is that of `terraform` version constraints.**
> 

### Cons of Legacy Tools Configuration

- The burden of constantly switching between one version and another
- It’s time-consuming just to access a tool
- Risk of breaking the system and re-installing from scratch
- Different virtual environments for each tool, such as Pyenv, nvm, rbenv
- Exports of multiple Paths as environmental variables

### How Asdf works

**Asdf** operates similar to nvm and other tool version managers but is not limited to a specific tool. Asdf uses plugins and this approach removes the constraints that a tool manager manages per tool with its own version file and commands. Thus, `asdf` is a single command for accessing all tools through plugins and manages the versions through `.tool-verions` file

> *Once `asdf` core is set up with your Shell configuration, plugins are installed to manage particular tools. When a tool is installed by a plugin, the executables that are installed have **[shimsopen in new window](https://en.wikipedia.org/wiki/Shim_(computing))** created for each of them. When you try and run one of these executables, the shim is run instead, allowing `asdf` to identify which version of the tool is set in `.tool-versions` and execute that version.*
> 

[asdf page](https://asdf-vm.com/guide/introduction.html#related-projects:~:text=Once%20asdf%20core,%23)

Here is how asdf manages multiple tools I work with `asdf list`


![list of Asdf Plugins](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8efg0o9wvgnur4thyodd.png)

### Asdf Setup

Two method for installing asdf 

- Git
- Package manager

### Git

```bash
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.10.2
```

Export the path 

```bash
. $HOME/.asdf/asdf.sh
```

Check the [asdf page](https://asdf-vm.com/guide/getting-started.html#_2-download-asdf) for specific installation according to your setup

**USAGE**

Install the dependencies first before you proceeds. `brew install gpg gawk`

Let’s install `istio` 

- First, find the plugin

```bash
# find the plugin
asdf plugin list all | grep -i istio
```

- Add the plugin

```bash
# add the plugin
asdf plugin add istioctl
```

![List available versions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kqq5ezio8rirdj7gvdj6.png)

- List available versions

```bash
# list available versions
asdf list all istioctl
```

![list of istio versions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ueztndd533pr8oy8032s.png)

- Install the version

```bash
# install version 1.14.3
asdf install istioctl 1.14.3
```

- List installed istio versions

```bash
# list the installed versions
asdf list istioctl
```

![installing istio](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nhj3vui1j6fpuf5llr8.png)

### Version File

Asdf uses `.tool-versions` file to track which version to use when the command is invoked. Let’s see what happens when istio cli tool  `istioctl` is invoked. 

```bash
istioctl
```

![istioctl](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wq3zf6cnp05yab8qfj0q.png)

If the version is not set, asdf complains with this error ☝️

Let set the version 1.15.0

1. Open the `.tool-versions` file 
2. Add the version as the 👇

```bash
istioctl 1.15.0
```

![istio config in .tool-versions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jxyyv9slfkvwcxdo9aa6.png)

1. Save the file

Try it again, istioctl will display the usage just like this 👇

```bash
istioctl
```

![istio is working](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n226oh094dq6eocw479d.png)

### How To Set Version

There are two types of versions and this sublimes the problems of tools versioning.

1. Global Versioning

2. Local Versioning

> *There are two approaches to set versioning for asdf. The declarative and the imperative approach. If you are DevOps Engineer or Software Developer you probably prefer the declarative approach. Though the imperative way is faster.*
> 

**Quick check** 

**which version is the current global**

```bash
asdf current istioclt
```

[istio current version](Tool%20Version%20Manager%20e8280abe22094d219853ee02bf075e40/Screen_Recording_2022-09-20_at_3.56.27_PM.mov)

### Global Versioning

Recall the configuration of `.tool-versions` file as in this [block](https://www.notion.so/Tool-Version-Manager-e8280abe22094d219853ee02bf075e40). That was global versioning. It turns out that by default `asdf` is a global version. 

- **Declarative Approach** is the first approach by creating a `.tool-versions` file and adding the tool-name, then space, the version-number.

```bash
istioctl 1.15.0
```

- **Imperative Approach** is the use of cli with the `asdf` command and the flag `global`. Here is an example on how to do that 👇.

```bash
asdf global istioctl 1.15.0
```

Let's promote the second version of [istio 1.14.3](https://www.notion.so/Tool-Version-Manager-e8280abe22094d219853ee02bf075e40) to global using the imperative approach 👇

```bash
asdf global istioctl 1.14.3
```

![istio global versions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwvudppqcu8tam2nqenh.png)

The `asdf global` command updated the tool from 1.15.0 to 1.14.3 in `.tool-versions` file. You see the imperative approach is faster but the declarative approach is safer.

### Local Versioning

Local versioning allows you to set the tool version at project level. 

What does that even mean? 

You are allowed to set a version according to your working directory. Let’s try the two approaches.

- **Declarative Approach** for local versioning is similar to the global versioning as [previously discussed](https://www.notion.so/Tool-Version-Manager-e8280abe22094d219853ee02bf075e40). The difference is the directory. The Global version uses the `.tool-versions` file in the **$HOME** directory while the Local version uses the `.tool-versions` in the working **$PWD** directory.

Create a .tool-versions file in your project directory and add the tool, then space, the version number `istioctl 1.15.0`. See the illustration using the imperative approach.

- **Imperative Approach**

The istio_confidential is my project directory where I want to use istio 1.15.0

```bash
cd istio_confidential

asdf local istioctl 1.15.0

# view the .tool-versions file
cat .tool-versions
```

![istio imperative](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idg6xiyjyfep7j5o53z7.png)

A .tool-versions file is created and version 1.15.0 is set for this project.

Next, check the current istioctl version in the project directory (local) and outside the directory (global) 👇

```bash
asdf current istioctl
```

![istio versions locally and globally](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/smrobzv1hqpma90pawdz.png)

💪 Congratulations !!! 

You have installed asdf, added plugins and configure the versions, globally and locally. You have also successfully set two different istio versions on your machine, one for your project and the other globally accessible. 

You can install many versions and set different versions for different projects.