mcmillanj

John McMillan

Posted on January 29, 2024

tfenvy

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:

  1. Copy the script below and place it in a suitable PATH for you, making sure it's executable.
  2. 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
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
mcmillanj
John McMillan

Posted on January 29, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

tfenvy
terraform tfenvy

January 29, 2024