John McMillan
Posted on January 29, 2024
Terraform / Git-Bash / Windows
For almost four years I'd been using a Macbook as my main work machine. One quality of life tool I'd gotten used to was tfenv, a lovely little tool for managing terraform versions & quickly switching between them.
I'm now using a Windows machine as my main work laptop having recently started a new job. I'm fairly pragmatic and don't really mind what OS my work laptop runs... at least until I found out that tfenv wasn't available on Windows/git-bash. Sad face.
I was jealous that I wouldn't be able to use tfenv any more... I wanted something like tfenv for git-bash... tfenvy was born.
If you're starting to think I'm only writing this article because I'm super proud of the punny name I came up with... you would be right, but still, this might be useful to you if you're using git-bash on Windows to manage terraform code.
'tfenvy' allows you to
- List available versions of terraform (stable versions only).
- List locally installed versions of terraform.
- Download a specific version of terraform locally.
- Activate a specific version of terraform to use.
- Update to the latest version of terraform for windows.
- Remove a version of terraform you no longer need.
I don't have an installer yet, but it's simple to setup:
- Copy the script below and place it in a suitable PATH for you, making sure it's executable.
- Update TF_DIR and replace YOURUSERNAME with your user name, and make sure you have a 'bin' folder, sorry - directory, there.
#!/usr/bin/sh
# A super basic attempt to recreate the benefits of choosing a tf version since tfenv isn't yet supported on windows.
# Set Variables:
TF_DOWNLOAD="https://releases.hashicorp.com/terraform/"
TF_DIR="/c/Users/YOURUSERNAME/bin"
NUMARGS=$#
####################################################################################################################
# FUNCTIONS - anything we might need to do more than once - write a function for.
#
# Function to find current ACTIVE version of terraform
#
list_active_tf () {
CURRENT=`terraform -v 2> /dev/null | head -1 | cut -f 2 -d v`
if [ -z $CURRENT ] ; then
echo "TF not currently installed."
exit 1
else
export CURRENT
fi
}
#
# Function to list ALL available stable releases of terraform
#
list_online_versions () {
curl -s $TF_DOWNLOAD | grep href | egrep -v "alpha|rc|beta" | sort -n | cut -f 3 -d /
}
#
# Function to find the LATEST stable release of terraform
#
list_latest_version (){
LATEST=`list_online_versions | tail -1`
export LATEST
}
#
# Function to compare semantic formatted versions (e.g. 1.2.3)
# Credit to: https://stackoverflow.com/questions/4023830/how-to-compare-two-strings-in-dot-separated-version-format-in-bash
#
vercomp () {
if [[ $1 == $2 ]]
then
return 0
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
return 1
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
return 2
fi
done
return 0
}
#
# Function to compare current version with latest available
#
compare_versions () {
list_latest_version
list_active_tf
vercomp $LATEST $CURRENT
if [ $? == "1" ] ; then
echo "Update available. Latest=${LATEST}. Current=${CURRENT}."
else
echo "Latest version, ${LATEST}, already installed."
fi
}
#
# Function to list installed versions of terraform
#
list_local_versions () {
ls $TF_DIR | grep ^terraform-[0-9]*
}
#
# Function to activate the choosen version of terraform
#
activate_tf_version () {
cp -p ${TF_DIR}/terraform-${WANTED}.exe ${TF_DIR}/terraform.exe
}
#
# Function to download a specific version of terraform
#
get_tf (){
curl -s ${TF_DOWNLOAD}${WANTED}/terraform_${WANTED}_windows_amd64.zip -o /tmp/terraform_${WANTED}_windows_arm64.zip
unzip -qp /tmp/terraform_${WANTED}_windows_arm64.zip > ${TF_DIR}/terraform-${WANTED}.exe
}
#
# Function to install the latest version of terraform
#
get_latest_tf () {
list_latest_version
WANTED=$LATEST
get_tf
}
#
# Function to DELETE a specific version of terraform
#
remove_tf (){
rm -i ${TF_DIR}/terraform-${WANTED}.exe
}
#
# Function to print usage message
#
print_usage () {
echo "Usage:"
echo " -a <version> Activate terraform <version>."
echo " e.g. `basename $0` -a 1.6.6"
echo ""
echo " -d <version> Download a specific terraform <version>."
echo " e.g. `basename $0` -d 1.0.1"
echo ""
echo " -i List all installed versions of terraform. "
echo " e.g. `basename $0` -i"
echo ""
echo " -l List all stable Terraform versions available from Hashicorp. "
echo " e.g. `basename $0` -l"
echo ""
echo " -R <version> Remove the specified terraform <version>."
echo " e.g. `basename $0` -R 1.0.0"
echo ""
echo " -u Update to latest stable version of terraform."
echo " e.g. `basename $0` -u"
echo ""
}
# End of Functions section. Fun starts now!
####################################################################################################################
# Define Flags
while getopts 'a:ilud:R:' OPTION; do
case "$OPTION" in
a)
WANTED="$OPTARG"
activate_tf_version
;;
i)
list_local_versions
;;
l)
list_online_versions
;;
u)
get_latest_tf
activate_tf_version
;;
d)
WANTED="$OPTARG"
get_tf
;;
R)
WANTED="$OPTARG"
remove_tf
;;
*)
print_usage
exit 1
;;
esac
done
shift "$((OPTIND -1))"
if [ $NUMARGS == 0 ] ; then
print_usage
exit
fi
Posted on January 29, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.