Skip to content

Instantly share code, notes, and snippets.

@westonplatter
Created October 13, 2025 23:42
Show Gist options
  • Select an option

  • Save westonplatter/5563d9dc5d687e8673996a2b905e1aab to your computer and use it in GitHub Desktop.

Select an option

Save westonplatter/5563d9dc5d687e8673996a2b905e1aab to your computer and use it in GitHub Desktop.
terraform-cleanup-script.sh
#!/bin/bash
# Terraform Cleanup Script
# This script finds and allows deletion of .terraform folders
set -e
echo "=================================="
echo " TERRAFORM FOLDER CLEANUP"
echo "=================================="
echo ""
# Get the path to scan (default to HOME if not provided)
SCAN_PATH="${1:-$HOME}"
# Validate the path exists
if [ ! -d "$SCAN_PATH" ]; then
echo "ERROR: Path '$SCAN_PATH' does not exist or is not a directory."
exit 1
fi
# Convert to absolute path
SCAN_PATH=$(cd "$SCAN_PATH" && pwd)
echo "Scanning for .terraform folders in: $SCAN_PATH"
echo "This may take a moment..."
echo ""
# Show progress bar during scan
show_progress() {
local pid=$1
local delay=0.1
local spinstr='|/-\'
local bar_width=50
local progress=0
while kill -0 "$pid" 2>/dev/null; do
# Calculate progress (oscillate between 0-100 since we don't know real progress)
local pos=$((progress % (bar_width * 2)))
if [ $pos -ge $bar_width ]; then
pos=$((bar_width * 2 - pos))
fi
# Build progress bar
printf "\r["
for ((i=0; i<bar_width; i++)); do
if [ $i -eq $pos ]; then
printf "="
else
printf " "
fi
done
printf "] Scanning..."
progress=$((progress + 1))
sleep $delay
done
# Clear the progress bar line
printf "\r%*s\r" $((bar_width + 15)) ""
}
# Find all .terraform directories (compatible with bash 3.x)
TERRAFORM_DIRS=()
TEMP_FILE=$(mktemp)
# Run find in background and show progress
find "$SCAN_PATH" -type d -name ".terraform" 2>/dev/null > "$TEMP_FILE" &
FIND_PID=$!
show_progress $FIND_PID
wait $FIND_PID
# Read results from temp file
while IFS= read -r dir; do
TERRAFORM_DIRS+=("$dir")
done < "$TEMP_FILE"
rm -f "$TEMP_FILE"
# Check if any were found
if [ ${#TERRAFORM_DIRS[@]} -eq 0 ]; then
echo "No .terraform folders found in $SCAN_PATH"
exit 0
fi
echo "Found ${#TERRAFORM_DIRS[@]} .terraform folder(s):"
echo "-------------------------------------------"
# Create temporary file to store directory sizes in bytes for sorting
TEMP_SIZES=$(mktemp)
# Get sizes in bytes for sorting
for dir in "${TERRAFORM_DIRS[@]}"; do
size_bytes=$(du -sk "$dir" 2>/dev/null | cut -f1)
echo "$size_bytes|$dir" >> "$TEMP_SIZES"
done
# Sort by size (largest first) and rebuild arrays
SORTED_TERRAFORM_DIRS=()
declare -a SIZES
while IFS='|' read -r size_bytes dir; do
SORTED_TERRAFORM_DIRS+=("$dir")
# Convert back to human-readable format for display
size=$(du -sh "$dir" 2>/dev/null | cut -f1)
SIZES+=("$size")
done < <(sort -rn "$TEMP_SIZES")
rm -f "$TEMP_SIZES"
# Replace original array with sorted array
TERRAFORM_DIRS=("${SORTED_TERRAFORM_DIRS[@]}")
# Display all found folders with sizes (now sorted)
for i in "${!TERRAFORM_DIRS[@]}"; do
printf "%3d. [%8s] %s\n" $((i+1)) "${SIZES[$i]}" "${TERRAFORM_DIRS[$i]}"
done
echo ""
# Calculate total size
TOTAL_SIZE=$(du -shc "${TERRAFORM_DIRS[@]}" 2>/dev/null | tail -1 | cut -f1)
echo "Total size: $TOTAL_SIZE"
echo ""
# Main menu
while true; do
echo "What would you like to do?"
echo " 1) Select individual folders to delete"
echo " 2) Delete all .terraform folders"
echo " 3) Delete none (exit)"
echo ""
read -p "Enter your choice (1-3 or 'exit'): " choice
# Check for exit command
if [[ "$choice" == "exit" ]]; then
echo "Exiting. No changes made."
exit 0
fi
case $choice in
1)
# Select individually
echo ""
echo "Enter the numbers of folders to delete (space-separated)."
echo "Example: 1 3 5"
echo ""
read -p "Folder numbers: " -a selections
FOLDERS_TO_DELETE=()
for num in "${selections[@]}"; do
# Validate number
if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le ${#TERRAFORM_DIRS[@]} ]; then
idx=$((num-1))
FOLDERS_TO_DELETE+=("${TERRAFORM_DIRS[$idx]}")
else
echo "Warning: Invalid selection '$num' - skipping"
fi
done
if [ ${#FOLDERS_TO_DELETE[@]} -eq 0 ]; then
echo "No valid folders selected. Exiting."
exit 0
fi
break
;;
2)
# Delete all
FOLDERS_TO_DELETE=("${TERRAFORM_DIRS[@]}")
break
;;
3)
# Exit
echo "No folders will be deleted. Exiting."
exit 0
;;
*)
echo "Invalid choice. Please enter 1, 2, 3, or 'exit'."
echo ""
;;
esac
done
# Show what will be deleted
echo ""
echo "=================================="
echo "FOLDERS TO BE DELETED:"
echo "=================================="
for dir in "${FOLDERS_TO_DELETE[@]}"; do
# Find the size for this directory
for i in "${!TERRAFORM_DIRS[@]}"; do
if [ "${TERRAFORM_DIRS[$i]}" = "$dir" ]; then
printf "[%8s] %s\n" "${SIZES[$i]}" "$dir"
break
fi
done
done
# Calculate size of folders to delete
DELETE_SIZE=$(du -shc "${FOLDERS_TO_DELETE[@]}" 2>/dev/null | tail -1 | cut -f1)
echo ""
echo "Total size to be freed: $DELETE_SIZE"
echo ""
# Final confirmation
read -p "Are you sure you want to delete ${#FOLDERS_TO_DELETE[@]} folder(s)? [N/yes]: " confirmation
# Default to "no" if empty or anything other than "yes"
if [[ "$confirmation" != "yes" ]]; then
echo "Deletion cancelled. No changes made."
exit 0
fi
# Perform deletion
echo ""
echo "Deleting folders..."
DELETED_COUNT=0
FAILED_COUNT=0
for dir in "${FOLDERS_TO_DELETE[@]}"; do
if rm -rf "$dir" 2>/dev/null; then
echo "✓ Deleted: $dir"
((DELETED_COUNT++))
else
echo "✗ Failed to delete: $dir"
((FAILED_COUNT++))
fi
done
echo ""
echo "=================================="
echo "CLEANUP COMPLETE"
echo "=================================="
echo "Deleted: $DELETED_COUNT folder(s)"
if [ $FAILED_COUNT -gt 0 ]; then
echo "Failed: $FAILED_COUNT folder(s)"
fi
echo "Space freed: ~$DELETE_SIZE"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment