Sergii Vershynskyi
Sergii Vershynskyi
Creator of this blog.
Jul 13, 2023 3 min read 552 words

TERRAFORM CLI HELPER SCRIPT

Abstract: Working with multiple Terraform repositories can bring some inconveniences due to them using different configurations. This article is devoted to improving developer experience by creating a solution which abstracts away Terraform binary names for Terraform repositories.

Introduction

Imagine that your infrastructure lives in a lot of Terraform repositories. Over time, these repositories will start using distinct Terraform versions for different reasons, for example, because different teams own them. If you are using the bastion host to provision your infrastructure, you will have a bunch of Terraform binaries installed there.

While working with a specific Terraform repository, the first step would be to determine which Terraform version it requires. This might seem like a trivial task, but it will take time to do and can complicate by the fact that different teams can prefer unique locations to define Terraform version in their repositories. This is easy to automate by the shell script, bringing convenience and eliminating the necessity to do this repetitive task.

Terraform binary helper script

Each Terraform repository contains directories with configurations for different environments, for example: env-alpha, env-dev, env-staging, env-prod, etc. Let’s imagine that team 1 prefers to use file versions.tf to define Terraform version in its Terraform repositories, whereas team 2 uses initialize.tf. Both these files contain the same standard configuration block:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.5.0"
    }
  }

  required_version = "1.5.1"
}

#OTHER_CONTENT

In this case, we can find the right Terraform binary using the following code:

extract_version() {
  version=`grep -F $1 $2 | cut -d'"' -f 2 | tr -dc '0-9.\n'`
}

if [ -f versions.tf ]; then
  extract_version 'required_version' 'versions.tf'
elif [ -f initialize.tf ]; then
  extract_version 'required_version' 'initialize.tf'
fi

We download all required Terraform versions on the bastion host and rename them to follow the pattern tf{VERSION} (for example, for TF v1.5.1 the binary name would be tf1.5.1). This way, there is no need to modify the bash script when adding future versions of Terraform - only adding a new binary will be sufficient. The next section of the bash script is converting Terraform version to the corresponding Terraform binary name:

if [ -z $version ]; then
  echo 'Error: cannot find TF binary.'
 
  current_dir=${PWD##*/}
 
  if ! grep -q 'env-' <<< $current_dir; then
    echo 'Please make sure you are inside env-{ENV_NAME} directory.'
  fi
 
  exit 1
else
  binary="tf$version"
fi

The last step is invoking Terraform binary by passing all command line parameters to it:

$binary "$@"

Thus, now there is no need to run tf1.3.3 plan -out plan.tfplan or tf1.5.1 plan -out plan.tfplan in different Terraform repositories - you can just run tf plan -out plan.tfplan in all of them instead (!).

Conclusion

In this article, we discussed the solution for streamlining the usage of different Terraform CLI versions in the repositories. In particular, the proposed bash script can be useful to improve developer experience if you have multiple Terraform repositories which use different versions of Terraform CLI.

I hope you enjoyed this article and that you’ll find it helpful.

Happy coding!

Disclaimer: Code and article content are provided ‘as-is’ without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of code or article content.

You can find the complete source code for building this solution here.