Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load terraformsh config from parent directory #19

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
55 changes: 43 additions & 12 deletions terraformsh
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ _usage () {
TFVARS or COMMANDs.

-f FILE A file passed to Terraform's -var-file option.
Defaults to 'terraform.sh.tfvars' and 'terraform.sh.tfvars.json'
if not provided.
( config: VARFILES= )
-b FILE A file passed to Terraform's -backend-config option.
Defaults to 'backend.sh.tfvars' if not provided.
( config: BACKENDVARFILES= )
-C DIR Change to directory DIR.
( config: CD_DIR= )
-c file Specify a '.terraformshrc' configuration file to load.
-E EXPR Evaluate an expression in bash ('eval EXPR').
-I Disables automatically loading any 'terraform.sh.tfvars',
'terraform.sh.tfvars.json', or 'backend.sh.tfvars' files
'terraform.sh.tfvars.json', or 'backend.sh.tfvars' files
found while recursively searching parent directories.
( config: INHERIT_TFFILES=0 )
-P Do not use '.plan' files for plan/apply/destroy commands.
Expand Down Expand Up @@ -183,7 +186,7 @@ _cmd_console () {
declare -a args=("$@")
_runcmd "$TERRAFORM" console "${VARFILE_ARG[@]}" "${CONSOLE_ARGS[@]}" "${args[@]}"
}
# Note: this line may need to be modified to pipe 'yes no | ' to the beginning
# Note: this line may need to be modified to pipe 'yes no | ' to the beginning
# of the Terraform command, if you notice any problems with init in the future.
_cmd_init () {
[ "${_already_ran_cmd_init:-0}" = "1" ] && return 0
Expand Down Expand Up @@ -293,6 +296,7 @@ _cmd_aws_bootstrap () {

# Look though the backend var files for the backend bucket and dynamodb_table
for varfile in "${BACKENDVARFILES[@]}" ; do
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: Searching for S3 Bucket and Dynamodb settings from $varfile ..." 1>&2
TF_BACKEND_BUCKET="${TF_BACKEND_BUCKET:-$( grep -e "^[[:space:]]*bucket[[:space:]]\+=" < "$varfile" | sed -E 's/^[[:space:]]*bucket[[:space:]]+=[[:space:]]*//; s/^"//g; s/"$//g' )}"
TF_BACKEND_TABLE="${TF_BACKEND_TABLE:-$( grep -e "^[[:space:]]*dynamodb_table[[:space:]]\+=" < "$varfile" | sed -E 's/^[[:space:]]*dynamodb_table[[:space:]]+=[[:space:]]*//; s/^"//g; s/"$//g' )}"
done
Expand Down Expand Up @@ -399,6 +403,7 @@ _default_vars () {
# when found in any parent directories (disable with the '-I' option).
TF_BACKEND_AUTO_CONFIG_FILE="${TF_BACKEND_AUTO_CONFIG_FILE:-backend.sh.tfvars}"
TF_AUTO_CONFIG_FILE="${TF_AUTO_CONFIG_FILE:-terraform.sh.tfvars}"
declare -a TFSH_AUTO_CONFIG_FILES=(.terraformshrc terraformsh.conf)

# This enables the above functionality by default ('-I' sets this to 0)
INHERIT_TFFILES="${INHERIT_TFFILES:-1}"
Expand Down Expand Up @@ -460,24 +465,39 @@ _final_vars () {
_load_conf () {
# Don't load the default configs if one was passed via '-c'
if [ ${#CONF_FILE[@]} -lt 1 ] ; then
for f in "/etc/terraformsh" ~/.terraformshrc "./.terraformshrc" "terraformsh.conf" ; do
[ -e "$f" ] && . "$(_readlinkf "$f")"
for file in /etc/terraformsh ~/.terraformshrc "${TFSH_AUTO_CONFIG_FILES[@]}" ; do
while read -r LINE ; do tfshconffiles=("$LINE") ; done < <(_rfindfiles "$file")
declare -a files=("$file" "${tfshconffiles[@]}")
for f in "${files[@]}" ; do
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: Searching for default terraformsh config file $f ..." 1>&2
if [ -e "$f" ] ; then
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: Loading default terraformsh config file $f ..." 1>&2
. "$(_readlinkf "$f")"
fi
done
done
# If '-c' was passed, let the user pass only the configs they want to load.
elif [ ${#CONF_FILE[@]} -gt 0 ] ; then
for conf in "${CONF_FILE[@]}" ; do
# NOTE: This is not a replacement for 'readlink -f'; if you want
# that behavior, pass the real file path yourself, don't rely on this.
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: Loading custom terraformsh config file $conf ..." 1>&2
. "$(_readlinkf "$conf")"
done
fi
return 0
}
# This function extracts the list of files matching the expected patterns in the parents
# folders and append them to the list of files to load.
_load_parent_tffiles () {
if [ "${INHERIT_TFFILES:-0}" = "1" ] ; then
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: Searching for $TF_AUTO_CONFIG_FILE files in current and parent folders ..." 1>&2
while read -r LINE ; do VARFILES=("$LINE" "${VARFILES[@]}") ; done < <( _rfindfiles "$TF_AUTO_CONFIG_FILE" )
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: Searching for $TF_AUTO_CONFIG_FILE.json files in current and parent folders ..." 1>&2
while read -r LINE ; do VARFILES=("$LINE" "${VARFILES[@]}") ; done < <( _rfindfiles "$TF_AUTO_CONFIG_FILE.json" )
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: Searching for $TF_BACKEND_AUTO_CONFIG_FILE files in current and parent folders ..." 1>&2
while read -r LINE ; do BACKENDVARFILES=("$LINE" "${BACKENDVARFILES[@]}") ; done < <( _rfindfiles "$TF_BACKEND_AUTO_CONFIG_FILE" )
#while read -r LINE ; do
fi
}
# This function takes an array and processes it for arguments from the Terraformsh
Expand All @@ -494,12 +514,16 @@ _process_cmds () {
if [ ! "$(expr "$cmd" : ".*\.backend\.tfvars$")" = "0" ] \
|| [ ! "$(expr "$cmd" : ".*\.backend\.sh\.tfvars$")" = "0" ] \
|| [ ! "$(expr "$cmd" : ".*\.backend$")" = "0" ]
then BACKENDVARFILES+=("$(_readlinkf "$cmd")")
then
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: We will try to use the Backend file $cmd ..." 1>&2
BACKENDVARFILES+=("$(_readlinkf "$cmd")")
elif [ "$(expr "$cmd" : ".*\.tfvars$")" -ne 0 ] \
|| [ "$(expr "$cmd" : ".*\.sh\.tfvars$")" -ne 0 ] \
|| [ "$(expr "$cmd" : ".*\.tfvars\.json$")" -ne 0 ] \
|| [ "$(expr "$cmd" : ".*\.sh\.tfvars\.json$")" -ne 0 ]
then VARFILES+=("$(_readlinkf "$cmd")")
then
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: We will try to use the TFVAR file $cmd ..." 1>&2
VARFILES+=("$(_readlinkf "$cmd")")
else break
fi
s=$((s+1))
Expand Down Expand Up @@ -538,7 +562,7 @@ _process_cmds () {
prev="opt"
else
echo "$0: Info: Found terraform command '$cmd'" 1>&2
CMD_PAIRS[$p]="array=($(printf "%q" "$cmd")" # Yes this has a leading '('
CMD_PAIRS[$p]="array=($(printf "%q" "$cmd")" # Yes this has a leading '('
found_cmds=$((found_cmds+1))
prev="cmd"
prevcmd="$cmd"
Expand All @@ -553,27 +577,34 @@ _process_cmds () {
}
_dirchange () {
if [ -n "${CD_DIR:-}" ] ; then
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: Changing working directory to $CD_DIR ..." 1>&2
printf "+ cd \"%s\"\n" "$CD_DIR" 1>&2
cd "$CD_DIR"
fi
}
_readlinkf () {
[ "${1:-}" ] || return 1; m_s=40; CDPATH=''; t=$1; [ -e "${t%/}" ] || t=${1%"${1##*[!/]}"}
[ -d "${t:-/}" ] && t="$t/"; cd -P . 2>/dev/null || return 1;
[ -d "${t:-/}" ] && t="$t/"; cd -P . 2>/dev/null || return 1;
while [ "$m_s" -ge 0 ] && m_s=$((m_s - 1)); do
if [ ! "$t" = "${t%/*}" ]; then case $t in
if [ ! "$t" = "${t%/*}" ]; then case $t in
/*) cd -P "${t%/*}/" || break ;;
*) cd -P "./${t%/*}" || break ;;
esac; t=${t##*/}; fi
if [ ! -L "$t" ]; then t="${PWD%/}${t:+/}${t}"; printf '%s\n' "${t:-/}"; return 0; fi
link=$(ls -dl -- "$t" 2>/dev/null) || break; t=${link#*" $t -> "}
done; return 1
}

# This function takes a file name as argument and search in the current and parents
# folders and return the full path of any file matching this name.
_rfindfiles () {
local file="$1"
cwd="$(pwd)"
while [ ! "$(dirname "$cwd")" = "/" ] ; do
[ ! -e "$cwd/$file" ] || printf "%s\n" "$cwd/$file"
if [ -e "$cwd/$file" ] ; then
[ "${DEBUG:-0}" -gt 0 ] && echo "$0: Debug: Found file $cwd/$file ..." 1>&2
printf "%s\n" "$cwd/$file"
fi
cwd="$(dirname "$cwd")"
done
}
Expand All @@ -586,7 +617,7 @@ _runcmd () {
# ------------------ parse cmdline options --------------------------- #

SHOW_HELP=0
declare -a BACKENDVARFILE_ARG=() BACKENDVARFILES=() VARFILE_ARG=() VARFILES=()
declare -a BACKENDVARFILE_ARG=() BACKENDVARFILES=() VARFILE_ARG=() VARFILES=()
declare -a REFRESH_ARGS=() INIT_ARGS=() IMPORT_ARGS=() GET_ARGS=() STATE_ARGS=()
declare -a PLAN_ARGS=() APPLY_ARGS=() PLANDESTROY_ARGS=() DESTROY_ARGS=()
declare -a CONSOLE_ARGS=() TAINT_ARGS=() UNTAINT_ARGS=() OUTPUT_ARGS=()
Expand Down Expand Up @@ -638,7 +669,7 @@ for pair in "${CMD_PAIRS[@]}" ; do
name="${array[0]}" # array is defined in 'eval $pair'
if command -v _cmd_"$name" >/dev/null ; then
_cmd_"$name" "${array[@]:1}"
else
else
_cmd_catchall "$name" "${array[@]:1}"
fi
done