Last active
October 8, 2022 07:07
-
-
Save omkensey/244c9a33e89d438f7741606e3434b394 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
PROVIDERS_DEFAULT="aws,awscc,google,azurerm,azuread" | |
PROVIDERS="" | |
SEARCH_LOC_DEFAULT=$HOME | |
SEARCH_LOC="" | |
TF_BIN="" | |
STATE_FILE_NAME="terraform.tfstate" | |
search_states() { | |
if [ -z $SEARCH_LOC ]; then | |
echo "Error: search location cannot be an empty string." >&2 | |
exit 1 | |
fi | |
if ! [ -e "$SEARCH_LOC" ]; then | |
echo "Error: search location does not exist." >&2 | |
exit 1 | |
fi | |
if [ -z $PROVIDERS ]; then | |
echo "Error: provider list cannot be an empty string." >&2 | |
exit 1 | |
fi | |
if ! command -v jq 2>&1 >/dev/null && [ -z $QUIET_MODE ]; then | |
echo "Warning: jq not found, falling back to grep (may be less precise)" >&2 | |
fi | |
provider_arr=(${PROVIDERS//,/ }) | |
provider_num=${#provider_list[@]} | |
for provider in ${provider_arr[@]}; do | |
if [ -z $first_provider ]; then | |
PROVIDER_REGEX="^${provider}_" | |
first_provider="false" | |
else | |
PROVIDER_REGEX="$PROVIDER_REGEX|^${provider}_" | |
fi | |
done | |
STATE_LIST=$(find $SEARCH_LOC -name $STATE_FILE_NAME -type f 2>/dev/null) | |
for statefile in $STATE_LIST; do | |
if command -v jq 2>&1 >/dev/null; then | |
if ! [ -z $FIND_DATA_RESOURCES ]; then | |
result=$(jq -r '.resources[]|select((.mode == "managed") or (.mode == "data")).type' < $statefile 2>/dev/null | grep -E $PROVIDER_REGEX) | |
else | |
result=$(jq -r '.resources[]|select(.mode == "managed").type' < $statefile 2>/dev/null | grep -E $PROVIDER_REGEX) | |
fi | |
if ! [ -z "$result" ]; then | |
echo "${statefile}:" | |
echo "$result" | sort -u | |
fi | |
else | |
if ! [ -z $FIND_DATA_RESOURCES ]; then | |
result=$(grep -A 1 -E '^[[:blank:]]*"mode": "managed"|^[[:blank:]]*"mode": "data"' $statefile | grep -E '^[[:blank:]]*"type": ' | cut -d: -f2 | tr -d '," ' | grep -E $PROVIDER_REGEX) | |
else | |
result=$(grep -A 1 -E '^[[:blank:]]*"mode": "managed"' $statefile | grep -E '^[[:blank:]]*"type":' | cut -d: -f2 | tr -d '," ' | grep -E $PROVIDER_REGEX) | |
fi | |
if ! [ -z "$result" ]; then | |
echo "${statefile}:" | |
echo "$result" | sort -u | |
fi | |
fi | |
done | |
} | |
output_usage() { | |
if ! command -v jq 2>&1 >/dev/null && [ -z $QUIET_MODE ]; then | |
echo "Warning: jq not found. Cannot report Terraform version or reliably \ | |
parse tfstate files without jq." >&2 | |
TF_VERSION="unknown" | |
else | |
TF_VERSION=$($TF_BIN version -json | jq -r .terraform_version) | |
fi | |
usage_text="Provider search list: ${PROVIDERS} | |
Location to search for state files: ${SEARCH_LOC} | |
Current Terraform version: ${TF_VERSION} | |
Usage: $(basename $0) [options] [arguments] | |
-a, --all: Find data sources as well as managed resources. | |
-d, --search-dir: search the specified path (usually a directory but a | |
single file will work as well). | |
Defaults to the user's home directory. | |
-p, --providers: specifies the provider(s) to search for resources created | |
by. Multiple providers can be specified as a comma-separated list | |
without spaces. | |
Defaults to ${PROVIDERS_DEFAULT}. | |
-t, --tf-bin: Use a specific Terraform binary at [path]. If the given path | |
is not a valid executable file, a fatal error results. | |
By default the desired Terraform binary is assumed to be the first one in | |
the user's path; if there isn't one or you don't want to use that one, | |
you must use this option. | |
-q, --quiet: Suppress non-fatal warning output. | |
-h, --help: Display this usage info." | |
OUTPUT_FD="${1-"1"}" | |
echo "$usage_text" >&${OUTPUT_FD} | |
} | |
#optspec=":a:o:ev:h-:" | |
optspec=":ad:p:t:qh-:" | |
while getopts "$optspec" optchar; do | |
case "${optchar}" in | |
-) | |
case "${OPTARG}" in | |
all) | |
FIND_DATA_RESOURCES="true" | |
;; | |
providers) | |
PROVIDERS="${!OPTIND@L}"; OPTIND=$(( $OPTIND + 1 )) | |
;; | |
search-dir) | |
SEARCH_LOC="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 )) | |
;; | |
tf-bin) | |
TF_BIN="${!OPTIND}"; OPTIND=$(( $OPTIND + 1 )) | |
;; | |
quiet) | |
QUIET_MODE="1" | |
;; | |
help) | |
OUTPUT_USAGE="true" | |
;; | |
*) | |
if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then | |
echo "Unknown option --${OPTARG}" >&2 | |
echo "" >&2 | |
OUTPUT_USAGE_ERR="true" | |
fi | |
;; | |
esac | |
;; | |
a) | |
FIND_DATA_RESOURCES="true" | |
;; | |
d) | |
SEARCH_LOC="${OPTARG}" | |
;; | |
p) | |
PROVIDERS="${OPTARG@L}" | |
;; | |
t) | |
TF_BIN="${OPTARG}" | |
;; | |
q) | |
QUIET_MODE="1" | |
;; | |
h) | |
OUTPUT_USAGE="true" | |
;; | |
*) | |
if [ "$OPTERR" != 1 ] || [ "${optspec:0:1}" = ":" ]; then | |
echo "Unknown option -${optchar}" >&2 | |
echo "" >&2 | |
OUTPUT_USAGE_ERR="true" | |
fi | |
;; | |
esac | |
done | |
shift $((OPTIND-1)) | |
if ! [ -z $TF_BIN ] && ! command -v "$TF_BIN" 2>&1 > /dev/null; then | |
echo "Terraform not found or not executable at the specified path." >&2 | |
exit 1 | |
elif ! command -v terraform 2>&1 > /dev/null; then | |
echo "No Terraform executable found. Install Terraform in your execution \ | |
path or use -t/--tf-bin to point to its location." | |
else | |
TF_BIN=${TF_BIN:-"terraform"} | |
fi | |
PROVIDERS=${PROVIDERS:-$PROVIDERS_DEFAULT} | |
SEARCH_LOC=${SEARCH_LOC:-$SEARCH_LOC_DEFAULT} | |
if ! [ -z $OUTPUT_USAGE_ERR ]; then | |
output_usage 2 | |
exit 1 | |
fi | |
if ! [ -z $OUTPUT_USAGE ]; then | |
output_usage | |
exit 0 | |
fi | |
search_states |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment