Skip to content
Anton edited this page Mar 11, 2023 · 9 revisions

Table of content

Auto-install Terraform

This snippets depends on Direnv bin dir

Install terraform in your direnv directory IF no terraform binary is found.

Configuration environments variable:

  • TF_VERSION (defaults to '1.0.8' in this doc)
  • TF_ARCH (defaults to 'linux_amd64' in this doc)

In your .envrc:

#
# Auto-install Terraform
# ======================
#
[ -z "${TF_VERSION}" ] && export TF_VERSION="1.1.3"
[ -z "${TF_ARCH}" ] && export TF_ARCH="linux_amd64"
TF_PKG_NAME="terraform_${TF_VERSION}_${TF_ARCH}.zip"
TF_PKG_URL="https://releases.hashicorp.com/terraform/${TF_VERSION}/${TF_PKG_NAME}" 
TF_PKG_PATH="${DIRENV_TMP_DIR}/${TF_PKG_NAME}" 
if [ ! -e "${DIRENV_BIN_DIR}/terraform" ] || ! "${DIRENV_BIN_DIR}/terraform" --version | grep -q "Terraform v${TF_VERSION}"; then
    echo "===> Getting terraform:${TF_VERSION}:${TF_ARCH} (can take a while to execute)"
    curl -s -L "${TF_PKG_URL}" -o "${TF_PKG_PATH}"
    unzip ${TF_PKG_PATH} -d ${DIRENV_BIN_DIR}
    chmod 700 ${DIRENV_BIN_DIR}/terraform
    rm -f ${TF_PKG_PATH}
fi

Terragrunt replacement

Main .envrc file looks like this:

#Before copy-pasting this code please go to https://medium.com/@senior-devops/how-to-extend-terraform-with-direnv-a4a3fef092c5
#and press "clapp" button at the bottom three times! ;)

source_up

has aws
has jq

BASE_PWD=$PWD
# figures the current working directory without relying on PWD (which will change when direnv is done)
get_cwd() {
  p="$(expand_path "$1")"
  local t="${p%${p##*/}}"
  echo "${t%/}"
}

# Needed for nested .envrc files
use_terraform_env() {
  local CWD
  CWD="$(get_cwd "$1")"

  ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
  echo Current account ID: ${ACCOUNT_ID:-"UNDEFINED!!!"}, Region: ${AWS_REGION:-"UNDEFINED!!!"}
  echo Current PWD: $CWD

  #Environment name is just a concatenation of two nested folders (i.e. project-environment)
  ENVIRONMENT="$(basename ${CWD%/*})-$(basename $CWD)"

  #Check if tfvars files exist:
  for file in ${BASE_PWD}/vars/global.tfvars \
              ${BASE_PWD}/vars/global.etfvars \
              ${BASE_PWD}/vars/${ENVIRONMENT}.tfvars \
              ${BASE_PWD}/vars/${ENVIRONMENT}.etfvars
  do
    if [[ -f ${file} ]]; then
       TF_VAR_FILES="${TF_VAR_FILES:-} -var-file=${file}"
    fi
  done

  TF_COMMON_ARGS="-compact-warnings -input=false -lock-timeout=120s ${TF_VAR_FILES}"
  export TF_CLI_ARGS_plan="${TF_COMMON_ARGS}"
  export TF_CLI_ARGS_apply="${TF_COMMON_ARGS}"
  export TF_CLI_ARGS_import="${TF_COMMON_ARGS}"
  export TF_CLI_ARGS_destroy="${TF_COMMON_ARGS}"
  export TF_CLI_ARGS_console="${TF_VAR_FILES}"
  export TF_CLI_ARGS_refresh="${TF_COMMON_ARGS}"
  export TF_CLI_ARGS_init="-backend=true -get=true -backend-config="bucket=terraform-${ACCOUNT_ID}" -backend-config="key=$ENVIRONMENT.tfstate" -backend-config="workspace_key_prefix=$AWS_REGION/$ENVIRONMENT""
  export TF_PLUGIN_CACHE_DIR="${TF_PLUGIN_CACHE_DIR:=${BASE_PWD}/.plugin_cache}"
  export TF_VAR_region=${AWS_REGION}
}

Each terraform project has similar .direnv file which references the main .direnv:

source_up
#Use current PWD in upper .envrc
use terraform_env "$1"

More details can be found here.

Clone this wiki locally