#!/bin/bash

# ==========================================================================
# SCRIPT: iam_rotate_access_key.sh
# DESCRIPTION: Automates the rotation of AWS IAM access keys for a specified user.
#              This script creates a new access key, deactivates the old one,
#              deletes the old one, and saves the new access key to a specified
#              JSON file. This helps improve security by regularly changing credentials.
#
# USE CASE SCENARIO:
# An organization requires regular rotation of IAM user access keys (e.g., every 90 days)
# for security compliance. This script can be scheduled to automate this process
# for programmatic users, reducing manual effort and security risks.
#
# 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:
#     - `iam:ListAccessKeys`
#     - `iam:CreateAccessKey`
#     - `iam:UpdateAccessKey`
#     - `iam:DeleteAccessKey`
#     - These permissions should be granted on the specific IAM user whose keys are being rotated.
# 3.  **Existing Resources:**
#     - An existing IAM user for whom to rotate access keys.
#
# HOW TO USE:
# 1.  **Save the script:** Save this content as `iam_rotate_access_key.sh`.
# 2.  **Make it executable:** `chmod +x iam_rotate_access_key.sh`
# 3.  **Configure variables:** Open the script and update the `--- Configuration Variables ---
#     section with your specific environment details.
# 4.  **Run from your terminal:** `./iam_rotate_access_key.sh`
#
# IMPORTANT CONSIDERATIONS:
# - **CRITICAL:** The `OUTPUT_FILE_PATH` will contain the new secret access key in plain text.
#   Ensure this file is stored securely and its access is strictly controlled.
# - This script is designed for programmatic IAM users. For human users, consider using temporary
#   credentials (e.g., AWS SSO, MFA) instead of long-lived access keys.
# - Test thoroughly in a non-production environment before using in production.
# ==========================================================================

# --- Configuration Variables (REPLACE with your actual values) ---
IAM_USER_NAME="my-programmatic-user" # The IAM user name whose access key will be rotated
OUTPUT_FILE_PATH="/path/to/secure/location/new_access_key.json" # Path to save the new access key JSON
AWS_REGION="us-east-1"                 # AWS region (used for AWS CLI commands)
# ----------------------------------------------------------------

echo "Starting IAM access key rotation for user '${IAM_USER_NAME}' in region ${AWS_REGION}..."

# ==========================================================================
# STEP 1: List existing access keys for the user.
# We need to identify old keys to deactivate and delete them later.
# ==========================================================================
echo "
>>> Step 1: Listing existing access keys for user '${IAM_USER_NAME}'..."
EXISTING_KEYS_JSON=$(aws iam list-access-keys \
    --user-name "${IAM_USER_NAME}" \
    --query "AccessKeyMetadata" \
    --region "${AWS_REGION}" \
    --output json)

if [ $? -ne 0 ]; then
    echo "Error listing access keys for user '${IAM_USER_NAME}'. Exiting."
    exit 1
fi

EXISTING_KEY_COUNT=$(echo "${EXISTING_KEYS_JSON}" | jq '. | length')
echo "   Found ${EXISTING_KEY_COUNT} existing access key(s)."

# ==========================================================================
# STEP 2: Create a new access key for the user.
# This generates a new Access Key ID and Secret Access Key.
# ==========================================================================
echo "
>>> Step 2: Creating a new access key for user '${IAM_USER_NAME}'..."
NEW_KEY_RESPONSE=$(aws iam create-access-key \
    --user-name "${IAM_USER_NAME}" \
    --query "AccessKey" \
    --region "${AWS_REGION}" \
    --output json)

if [ $? -ne 0 ]; then
    echo "Error creating new access key. Exiting."
    exit 1
fi

NEW_ACCESS_KEY_ID=$(echo "${NEW_KEY_RESPONSE}" | jq -r '.AccessKeyId')
NEW_SECRET_ACCESS_KEY=$(echo "${NEW_KEY_RESPONSE}" | jq -r '.SecretAccessKey')
echo "   New Access Key ID created: ${NEW_ACCESS_KEY_ID}"

# ==========================================================================
# STEP 3: Save the new access key to a specified JSON file.
# CRITICAL: Ensure this file is stored securely and its access is controlled.
# ==========================================================================
echo "
>>> Step 3: Saving new access key to '${OUTPUT_FILE_PATH}'..."
NEW_KEY_DATA='{"AccessKeyId":"'${NEW_ACCESS_KEY_ID}'","SecretAccessKey":"'${NEW_SECRET_ACCESS_KEY}'","UserName":"'${IAM_USER_NAME}'","CreationDate":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}'
echo "${NEW_KEY_DATA}" | jq . > "${OUTPUT_FILE_PATH}"

if [ $? -eq 0 ]; then
    echo "   New access key saved successfully to '${OUTPUT_FILE_PATH}'."
    echo "   IMPORTANT: Securely store this file and restrict its access."
else
    echo "Error saving new access key to file. Exiting."
    exit 1
fi

# ==========================================================================
# STEP 4: Deactivate and delete old access keys.
# This ensures that only the newly created key is active.
# ==========================================================================
if [ "${EXISTING_KEY_COUNT}" -gt 0 ]; then
    echo "
>>> Step 4: Deactivating and deleting old access keys..."
    echo "${EXISTING_KEYS_JSON}" | jq -r '.[] | .AccessKeyId' | while read OLD_KEY_ID;
    do
        if [ "${OLD_KEY_ID}" != "${NEW_ACCESS_KEY_ID}" ]; then
            echo "   Deactivating old Access Key ID: ${OLD_KEY_ID}"
            aws iam update-access-key \
                --access-key-id "${OLD_KEY_ID}" \
                --status "Inactive" \
                --user-name "${IAM_USER_NAME}" \
                --region "${AWS_REGION}"

            echo "   Deleting old Access Key ID: ${OLD_KEY_ID}"
            aws iam delete-access-key \
                --access-key-id "${OLD_KEY_ID}" \
                --user-name "${IAM_USER_NAME}" \
                --region "${AWS_REGION}"
            echo "   Old Access Key ID ${OLD_KEY_ID} deleted."
        else
            echo "   Skipping deletion of newly created key: ${OLD_KEY_ID}"
        fi
    done
else
    echo "
>>> Step 4: No old access keys to deactivate/delete."
fi

echo "
=== IAM access key rotation for user '${IAM_USER_NAME}' completed successfully. ===
"
