Terraform is an Infrastructure as Code tool that enables automated managed deployments of IT Solutions. Ironically, installing and upgrading Terraform itself is a manual process. This post describes how to simplify your Terraform use with my automated Installer.
Intro: Terraform and Infrastructure as Code
Infrastructure as Code (IaC) can be simply described as enabling the details of an infrastructure to be written as code. The files that define the architecture can be easily used with version control systems and shared with team-mates. Additionally, it enables easy reuse of architectural components in other solutions.
IaC tools enable these files to be used for automated deployment, dynamic adjustment and management of entire IT Solutions. While many IaC tools are Cloud Provider specific, like: AWS CloudFormation and Azure ARM templates, Terraform supports dozens of providers including cloud, bare-metal and on-premise resources.
Each IaC tool has unique benefits and constraints that should be carefully considered before selecting one. This post does not imply nor suggest that Terraform is the “right” tool for your specific scenario.
An Unexpected Annoyance
Two benefits listed on Terraform’s website are “increase operator productivity” and “provides an elegant user experience“. Given those selling points you might assume they apply to installing and updating Terraform itself. Unfortunately, this is not the case.
Installing and updating Terraform is a manual process that is neither elegant nor productive. While this might be acceptable for a one time install, it becomes an annoying problem when every single update requires repeating this manual procedure. This isn’t ground-breaking news to those who found this post while searching for an installer.
Official Installation and Upgrade Process
The installation process described in Terraform’s documentation includes these steps:
- Visit the download page and locate the correct version for your OS and CPU architecture
- Download the package to your computer
- Extract the downloaded package into a pre-compiled executable
- Copy this binary file to a location in your system’s PATH
This process is cumbersome for many reasons:
- This is not a one-time procedure. It must be performed every time there’s an update.
- It’s a manual process requiring multiple steps using multiple applications
- The downloaded package is in “zip” format which is non-standard on Linux
- Extraction on Linux requires installation of a separate utility
- Terraform can easily address this by changing the build script to compress Linux packages in a Linux-native format such as “tar” or “gz”
Searching for a Solution
My immediate instinct was to search for an existing solution. While I found many existing scripts, they were all hard-coded to a specific use-case:
- Hard-coded to specific platform or processor type
- Hard-coded installation location
- Always installed the latest version (no option to specify a version)
- With tools of this nature, it’s sometimes necessary to use a specific version when a new version introduces a “breaking change”
While the perfect solution may exist somewhere, I didn’t find one after an hour of searching.
Creating a Terraform Installer
After failing to find an existing script that met my needs, I decided to write my own. This required a complicated decision in selecting a scripting language and creating algorithms to determine the latest version and CPU architecture (described below).
The Terraform Installer script, instructions and source code are located in this GitHub Repo.
Determining the scripting language
A true cross-platform script should run on Windows, Mac and Linux with the default toolset. However, there isn’t a common scripting language across all three platforms by default, so compromise is necessary. In the end, I selected Bash for the following reasons:
- Default shell on both Linux and Mac.
- Included with Windows 10 as part of the Linux Subsystem.
- Installable on Windows with either cygwin or Git for Windows.
In summary, selecting Bash addresses two platforms completely and the Windows bash environments. The only scenario not addressed is using Terraform in the Windows command prompt.
Installer Process Details
This final sections describes the main sections of the installer, the functions they perform and the reasoning behind some of the decisions.
Determine Version to Install
- If specified, install version specified with
- Otherwise, calculate latest version using the github REST API
Determine OS and CPU architecture
- Calculate the Download URL by combining Version, OS and CPU-Architecture
- Verifies the calculated URL is valid before proceeding in case:
- incorrect version specified with
- download URL format changed on the Terraform website.
- incorrect version specified with
Determine Installation Destination
- Automatically installs to
/usr/local/bin/in the following cases:
-aparameter specified or
- User has write access to
- Otherwise, prompt the user for destination location:
- user’s local
Perform Download and Install
- Download from URL previously calculated
- Extract the executable from downloaded package
- Move the executable to Destination previously determined
- Remove the downloaded package and temporary files
- Finally, display installation results, Terraform version and installation directory
As mentioned above, the Installer can be found in this GitHub Repo.