Skip to content

Instantly share code, notes, and snippets.

@rexwhitten
Last active July 3, 2025 21:08
Show Gist options
  • Select an option

  • Save rexwhitten/a470be4d8334799d530ba7114ac8e313 to your computer and use it in GitHub Desktop.

Select an option

Save rexwhitten/a470be4d8334799d530ba7114ac8e313 to your computer and use it in GitHub Desktop.
Terraform Scripts
#!/bin/bash
# Check if the JSON file is provided as an argument
if [ -z "$1" ]; then
echo "Usage: $0 <terraform-plan-output.json>"
exit 1
fi
# Function to get an emoticon based on the action
get_emoticon() {
case "$1" in
"create") echo "🟒" ;;
"update") echo "πŸ”΅" ;;
"delete") echo "πŸ”΄" ;;
"importing") echo "🟑" ;;
*) echo "❓" ;; # Unknown action
esac
}
# Parse the JSON and group by actions
jq -r '.resource_changes[] | "\(.address) \(.change.actions[0]) \(.change.importing)"' "$1" | while read -r line; do
address=$(echo "$line" | awk '{print $1}')
action=$(echo "$line" | awk '{print $2}')
importing=$(echo "$line" | awk '{print $3}')
# if importing is not null then change the action to "importing"
if [ "$importing" != "null" ]; then
action="importing"
fi
emoticon=$(get_emoticon "$action")
echo "$action $emoticon: $address"
done | sort | uniq -c | while read -r count action_emoticon; do
echo -e "$action_emoticon ($count)"
done
#!/bin/bash
# Terraform Scripted Planning Workflow with Enhanced Error Handling
#export TF_LOG=DEBUG
# Function to output errors to stderr
error() {
echo -e "\e[1;31mERROR:\e[0m $1" >&2
}
# Check if a working directory is provided
if [[ $# -eq 0 ]]; then
error "Please provide a working directory"
exit 1
fi
EXECUTION_DIR=$1
SDLC_ENV=${2:-"pr"}
# Validate if provided directory exists and is a directory
if [[ ! -d ${EXECUTION_DIR} ]]; then
error "The provided working directory '${EXECUTION_DIR}' does not exist or is not a directory"
exit 1
fi
# Validate if provided directory contains a Terraform configuration
if [[ ! -f "${EXECUTION_DIR}/main.tf" ]] && [[ ! -f "${EXECUTION_DIR}/terraform.tfvars" ]]; then
error "The directory '${EXECUTION_DIR}' does not contain a Terraform configuration (e.g., main.tf or terraform.tfvars)"
exit 1
fi
validate() {
# List of required environment variables
REQUIRED_ENV_VARS=()
# Check if each required environment variable is set
for VAR in "${REQUIRED_ENV_VARS[@]}"; do
if [ -z "${!VAR}" ]; then
echo "Error: Environment variable '$VAR' is not set."
exit 1
fi
done
echo "All required environment variables are set."
}
# Function to get an emoticon based on the action
get_emoticon() {
case "$1" in
"create") echo "🟒" ;;
"update") echo "πŸ”΅" ;;
"delete") echo "πŸ”΄" ;;
"importing") echo "🟑" ;;
*) echo "❓" ;; # Unknown action
esac
}
parse() {
# Parse the JSON and group by actions
jq -r '.resource_changes[] | "\(.address) \(.change.actions[0]) \(.change.importing) \(.action_reason)"' "$1" | while read -r line; do
address=$(echo "${line}" | awk '{print $1}')
action=$(echo "${line}" | awk '{print $2}')
importing=$(echo "${line}" | awk '{print $3}')
reason=$(echo "${line}" | awk '{print $4}')
# if importing is not null then change the action to "importing"
if [[ ${importing} != "null" ]]; then
action="importing"
fi
emoticon=$(get_emoticon "${action}")
# dont show ❓ items
if [[ ${emoticon} == "❓" ]]; then
continue
fi
prefix="⬛"
# identify iam and iam policy
if [[ ${address} == *"aws_iam_policy"* ]]; then
prefix="πŸ†”"
fi
if [[ ${address} == *"aws_iam_role"* ]]; then
prefix="πŸ‘€"
fi
if [[ ${address} == *"aws_iam_policy_attachment"* ]]; then
prefix="πŸ”—"
fi
if [[ ${address} == *"aws_iam_role_policy_attachment"* ]]; then
prefix="πŸ”—"
fi
echo "${action} ${emoticon}: ${prefix}${address} (${reason})"
done | sort | uniq -c | while read -r count action_emoticon; do
echo -e "${action_emoticon} (${count})"
done
}
# Executes the `terraform plan` command
execute() {
# Navigate to the execution directory, run commands, and handle any errors
if ! cd "${EXECUTION_DIR}"; then
error "Failed to change directory to '${EXECUTION_DIR}'"
return 1
fi
# Task
terraform plan \
-var-file="./env/${SDLC_ENV}.tfvars" \
-out=tfplan \
-lock=false \
-input=false &&
terraform show -json tfplan >./tfplan.json &&
parse ./tfplan.json &&
#terramaid --subgraph-name "module.example"
# Navigate back to original directory
if ! cd - >/dev/null; then
error "Failed to return to the original directory"
return 1
fi
}
main() {
validate
if ! execute; then
error "Plan failed. Please check the errors above."
exit 1
fi
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment