#!/bin/bash

# ==========================================================================
# SCRIPT: ebs_cleanup.sh
# DESCRIPTION: Cleans up unused Amazon EBS volumes and old snapshots using AWS CLI.
#              This script helps optimize costs by removing unattached volumes
#              and snapshots older than a specified age, after verifying they
#              are not attached to any AMIs.
#
# USE CASE SCENARIO:
# An organization wants to reduce AWS costs by automatically identifying and
# deleting EBS resources that are no longer in use or are past their retention
# period. This script can be run periodically to enforce cleanup policies.
#
# PREREQUISITES:
# 1.  **AWS CLI:** The AWS Command Line Interface must be installed and configured
#     with credentials that have the necessary permissions.
# 2.  **IAM Permissions:** The principal executing this script must have permissions to:
#     - `ec2:DescribeVolumes`
#     - `ec2:DeleteVolume` (if `DELETE_UNATTACHED_VOLUMES` is true. Use with caution!)
#     - `ec2:DescribeSnapshots`
#     - `ec2:DescribeImages` (to check if snapshots are attached to AMIs)
#     - `ec2:DeleteSnapshot` (if `DELETE_OLD_SNAPSHOTS` is true. Use with caution!)
#
# HOW TO USE:
# 1.  **Save the script:** Save this content as `ebs_cleanup.sh`.
# 2.  **Make it executable:** `chmod +x ebs_cleanup.sh`
# 3.  **Configure variables:** Open the script and update the `--- Configuration Variables ---
#     section with your specific environment details.
# 4.  **Run from your terminal:** `./ebs_cleanup.sh`
#
# IMPORTANT CONSIDERATIONS:
# - **USE WITH EXTREME CAUTION!** Deleting EBS volumes and snapshots is irreversible.
#   Always test in a non-production environment first.
# - Ensure you have proper backup and recovery strategies in place.
# - The script checks if snapshots are attached to AMIs before deletion. This is a critical safeguard.
# ==========================================================================

# --- Configuration Variables (REPLACE with your actual values) ---
AWS_REGION="us-east-1"                    # AWS region to perform cleanup
DELETE_UNATTACHED_VOLUMES="true"        # Set to "true" to delete unattached EBS volumes
DELETE_OLD_SNAPSHOTS="true"             # Set to "true" to delete snapshots older than SNAPSHOT_AGE_DAYS
SNAPSHOT_AGE_DAYS=30                      # Snapshots older than this many days will be deleted
# ----------------------------------------------------------------

echo "Starting EBS cleanup process in region ${AWS_REGION}...
"

# ==========================================================================
# STEP 1: Cleanup Unattached EBS Volumes (if enabled).
# Unattached volumes are those in 'available' state and not connected to any EC2 instance.
# ==========================================================================
if [ "${DELETE_UNATTACHED_VOLUMES}" = "true" ]; then
    echo ">>> Step 1: Cleaning up unattached EBS volumes..."
    # Describe volumes that are in 'available' state (i.e., unattached)
    UNATTACHED_VOLUMES=$(aws ec2 describe-volumes \
        --filters Name=status,Values=available \
        --query "Volumes[*].VolumeId" \
        --region "${AWS_REGION}" \
        --output text)

    if [ -z "${UNATTACHED_VOLUMES}" ]; then
        echo "   No unattached EBS volumes found."
    else
        echo "   Found unattached volumes: ${UNATTACHED_VOLUMES}"
        for VOLUME_ID in ${UNATTACHED_VOLUMES}; do
            echo "   Deleting unattached volume: ${VOLUME_ID}"
            aws ec2 delete-volume \
                --volume-id "${VOLUME_ID}" \
                --region "${AWS_REGION}" || { echo "Error deleting volume ${VOLUME_ID}. Continuing."; }
        done
        echo "   Initiated deletion for unattached EBS volumes."
    fi
else
    echo "Skipping cleanup of unattached EBS volumes as DELETE_UNATTACHED_VOLUMES is 'false'."
fi

# ==========================================================================
# STEP 2: Cleanup Old Snapshots (if enabled).
# Snapshots older than SNAPSHOT_AGE_DAYS will be considered for deletion.
# A critical check is performed to ensure snapshots are not attached to any AMIs.
# ==========================================================================
if [ "${DELETE_OLD_SNAPSHOTS}" = "true" ]; then
    echo "
>>> Step 2: Cleaning up snapshots older than ${SNAPSHOT_AGE_DAYS} days..."
    # Describe snapshots owned by the current account
    OLD_SNAPSHOTS=$(aws ec2 describe-snapshots \
        --owner-ids self \
        --query "Snapshots[?StartTime <= 
$(date -v-${SNAPSHOT_AGE_DAYS}d +%Y-%m-%dT%H:%M:%SZ)
].SnapshotId" \
        --region "${AWS_REGION}" \
        --output text)

    if [ -z "${OLD_SNAPSHOTS}" ]; then
        echo "   No old EBS snapshots found to delete."
    else
        echo "   Found old snapshots: ${OLD_SNAPSHOTS}"
        for SNAPSHOT_ID in ${OLD_SNAPSHOTS}; do
            # CRITICAL CHECK: Ensure the snapshot is not attached to any AMIs
            # Describe images that use this snapshot
            AMI_COUNT=$(aws ec2 describe-images \
                --filters Name=block-device-mapping.snapshot-id,Values=${SNAPSHOT_ID} \
                --query "Images | length(@)" \
                --region "${AWS_REGION}" \
                --output text)

            if [ "${AMI_COUNT}" -eq 0 ]; then
                echo "   Deleting old snapshot: ${SNAPSHOT_ID}"
                aws ec2 delete-snapshot \
                    --snapshot-id "${SNAPSHOT_ID}" \
                    --region "${AWS_REGION}" || { echo "Error deleting snapshot ${SNAPSHOT_ID}. Continuing."; }
            else
                echo "   Skipping snapshot ${SNAPSHOT_ID}: Attached to ${AMI_COUNT} AMI(s). Not deleting."
            fi
        done
        echo "   Initiated deletion for old EBS snapshots."
    fi
else
    echo "Skipping cleanup of old snapshots as DELETE_OLD_SNAPSHOTS is 'false'."
fi

echo "
=== EBS cleanup process completed. ===
"
