hashi-env lets you easily switch between multiple versions of the HashiCorp suite of tools. It's simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well.
This project was forked from pyenv and direnv, and modified for use with golang binaries.
Works with:
- Let you change the global version of the above HashiCorp tools, on a per-user basis.
- Provide support for per-project versions of the above HashiCorp tools.
- Allow you to override the tool version with an environment variable (e.g.,
TERRAFORM_VERSION). - Install and uninstall multiple versions of the above HashiCorp tools at the same time.
- Support Bash, KSH, ZSH, Fish, and may work with any other shell supporting Bash-like syntax.
- Not need to be loaded into your shell. Instead, hashi-env's shim approach works by adding a directory to your $PATH.
- GNU coreutils
- curl
- bash
At a high level, hashi-env intercepts commands using shim executables injected into your PATH, determines which version of the HashiCorp product has been specified by your application, and passes your commands along to the correct installation.
When you run a command like terraform or consul, your operating system searches through a list of directories to find an executable file with that name. This list of directories lives in an environment variable called PATH, with each directory in the list separated by a colon:
/usr/local/bin:/usr/bin:/bin
Directories in PATH are searched from left to right, so a matching executable in a directory at the beginning of the list takes precedence over another one at the end. In this example, the /usr/local/bin directory will be searched first, then /usr/bin, then /bin.
hashi-env works by inserting a directory of shims at the front of your PATH:
$(hashi-env root)/shims:/usr/local/bin:/usr/bin:/bin
Through a process called rehashing, hashi-env maintains shims in that directory to match every installed HashiCorp tool.
Shims are lightweight executables that simply pass your command along to hashi-env. So with hashi-env installed, when you run, say, terraform, your operating system will do the following:
- Search your
PATHfor an executable file namedterraform - Find the hashi-env shim for
terraformat the beginning of yourPATH - Run the shim named
terraform, which in turn passes the command along to hashi-env
When you execute a shim, hashi-env determines which tool version to use by reading it from the following sources, in this order:
- The TERRAFORM_VERSION environment variable (if specified)
- The application-specific
.terraform-versionfile in the current directory (if present). You can modify the current directory's.terraform-versionfile with thehashi-env localcommand. - The first
.terraform-versionfile found (if any) by searching each parent directory, until reaching the root of your filesystem. - The global
$(hashi-env root)/versionfile. You can modify this file using thehashi-env globalcommand. If the global version file is not present, hashi-env assumes you want to use the "system" version of the tool. (In other words, whatever version would run if hashi-env weren't in yourPATH.)
Once hashi-env has determined which version of the tool your application has specified, it passes the command along to the corresponding tool itself.
Each Terraform version is installed into its own directory under $(hashi-env root)/versions.
For example, you might have these versions installed:
$(hashi-env root)/versions/terraform-0.9.5/$(hashi-env root)/versions/terraform-0.11.14/$(hashi-env root)/versions/terraform-0.12.23/$(hashi-env root)/versions/terraform-0.12.24/$(hashi-env root)/versions/terraform-0.13.4/
As far as hashi-env is concerned, version names are simply the directories in $(hashi-env root)/versions.
This will get you going with the latest version of hashi-env and make it easy to fork and contribute any changes back upstream.
-
Check out hashi-env where you want it installed. A good place to choose is
$HOME/.hashi-env(but you can install it somewhere else).git clone https://github.com/thelonelyghost/hashi-env.git ~/.hashi-env
-
Add
~/.hashi-env/binto your$PATHfor access to thehashi-envcommand-line utility.-
For bash:
echo 'export PATH="$HOME/.hashi-env/bin:$PATH"' >> ~/.bash_profile
-
For Ubuntu Desktop:
echo 'export PATH="$HOME/.hashi-env/bin:$PATH"' >> ~/.bashrc
-
For zsh:
echo 'export PATH="$HOME/.hashi-env/bin:$PATH"' >> ~/.zshrc
-
For Fish shell:
set -Ux fish_user_paths $HOME/.hashi-env/bin $fish_user_paths
-
-
Add
eval "$(hashi-env init -)"to your shell to enable autocompletion and shims. Please make sureeval "$(hashi-env init -)"is placed toward the end of the shell configuration file since it manipulatesPATHduring the initialization.echo -e 'if command -v hashi-env 1>/dev/null 2>&1; then\n eval "$(hashi-env init -)"\nfi' >> ~/.bash_profile
- Zsh note: Modify your
~/.zshrcfile instead of~/.bash_profile. - fish note: Use
hashi-env init - | sourceinstead ofeval (hashi-env init -). - Ubuntu and Fedora note: Modify your
~/.bashrcfile instead of~/.bash_profile.
General warning: There are some systems where the
BASH_ENVvariable is configured to point to.bashrc. On such systems you should almost certainly put the above mentioned lineeval "$(hashi-env init -)"into.bash_profile, and not into.bashrc. Otherwise you may observe strange behaviour, such ashashi-envgetting into an infinite loop. See pyenv/pyenv#264 for details. - Zsh note: Modify your
-
Restart your shell so the path changes take effect. You can now begin using hashi-env.
exec "$SHELL"
-
Install HashiCorp product versions into
$(hashi-env root)/versions. For example, to download and install Consul 1.8.0, run:hashi-env install consul 1.8.0
If you've installed hashi-env using the instructions above, you can upgrade your installation at any time using git.
To upgrade to the latest development version of hashi-env, use git pull:
cd $(hashi-env root)
git pullTo upgrade to a specific release of hashi-env, check out the corresponding tag:
cd $(hashi-env root)
git fetch
git tag
git checkout v0.1.0The simplicity of hashi-env makes it easy to temporarily disable it, or uninstall from the system.
- To disable hashi-env managing your HashiCorp product versions, simply remove the
hashi-env initline from your shell startup configuration. This will remove hashi-env shims directory from PATH, and future invocations likenomadwill execute the system Nomad version, as before hashi-env.
hashi-env will still be accessible on the command line, but your Python apps won't be affected by version switching.
- To completely uninstall hashi-env, perform step (1) and then remove its root directory. This will delete all Terraform, Consul, Vault, Nomad, Packer, envconsul, and consul-template versions that were installed under
$(hashi-env root)/versions/directory:rm -rf $(hashi-env root)
Skip this section unless you must know what every line in your shell profile is doing.
hashi-env init is the only command that crosses the line of loading extra commands into your shell. Coming from rvm, some of you might be opposed to this idea. Here's what hashi-env init actually does:
-
Sets up your shims path. This is the only requirement for hashi-env to function properly. You can do this by hand by prepending
$(hashi-env root)/shimsto your$PATH. -
Installs autocompletion. This is entirely optional but pretty useful. Sourcing
$(hashi-env root)/completions/hashi-env.bashwill set that up. There is also a$(hashi-env root)/completions/hashi-env.zshfor Zsh users. -
Rehashes shims. From time to time you'll need to rebuild your shim files. Doing this on init makes sure everything is up to date. You can always run
hashi-env rehashmanually. -
Installs the sh dispatcher. This bit is also optional, but allows hashi-env and plugins to change variables in your current shell, making commands like
hashi-env shellpossible. The sh dispatcher doesn't do anything crazy like overridecdor hack your shell prompt, but if for some reason you needhashi-envto be a real script rather than a shell function, you can safely skip it.
To see exactly what happens under the hood for yourself, run hashi-env init -.
As time goes on, you will accumulate tool versions in your $(hashi-env root)/versions directory.
To remove old versions, hashi-env remove command to automate the removal process.
Alternatively, simply rm -rf the directory of the version you want to remove.
See COMMANDS.md.
You can affect how hashi-env operates with the following settings:
| name | default | description |
|---|---|---|
TERRAFORM_VERSION |
Specifies the terraform version to be used. | |
CONSUL_VERSION |
Specifies the consul version to be used. | |
NOMAD_VERSION |
Specifies the nomad version to be used. | |
VAULT_VERSION |
Specifies the vault version to be used. | |
PACKER_VERSION |
Specifies the packer version to be used. | |
ENVCONSUL_VERSION |
Specifies the envconsul version to be used. | |
CONSUL_TEMPLATE_VERSION |
Specifies the consul-template version to be used. | |
HASHIENV_DEBUG |
Outputs debug information. Also as: hashi-env --debug <subcommand> |
The hashi-env source code is hosted on GitHub. It's clean, modular, and easy to understand, even if you're not a shell hacker.
Tests, once written, will be executed using Bats:
bats test
bats/test/<file>.bats
Please feel free to submit pull requests and file bugs on the issue tracker.
See CHANGELOG.md.