Skip to content

Instantly share code, notes, and snippets.

@pcolazurdo
Created March 11, 2022 15:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pcolazurdo/7f2aa48e2be31b6335d30388494ded9b to your computer and use it in GitHub Desktop.
Save pcolazurdo/7f2aa48e2be31b6335d30388494ded9b to your computer and use it in GitHub Desktop.
#CAUTION: This will help you to delete all AWS IAM Policies that aren't attached to any resource Role. Treat carefully
#!/bin/bash
TEMP_DIR=$(mktemp -d)
echo Output Directory: ${TEMP_DIR}
confirm() {
#
# syntax: confirm [<prompt>]
#
# Prompts the user to enter Yes or No and returns 0/1.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>
#
# 04 Jul 17 0.1 - Initial version - MEJT
#
local _prompt _default _response
if [ "$1" ]; then _prompt="$1"; else _prompt="Are you sure"; fi
_prompt="$_prompt [y/n] ?"
# Loop forever until the user enters a valid response (Y/N or Yes/No).
while true; do
read -r -p "$_prompt " _response
case "$_response" in
[Yy][Ee][Ss]|[Yy]) # Yes or Y (case-insensitive).
return 0
;;
[Nn][Oo]|[Nn]) # No or N.
return 1
;;
*) # Anything else (including a blank) is invalid.
sleep 1
;;
esac
done
}
generate_policy_list() {
aws iam list-policies --scope Local --no-only-attached | jq '.Policies[].Arn' | sort > ${TEMP_DIR}/no-only-attached.csv
aws iam list-policies --scope Local --only-attached | jq '.Policies[].Arn' | sort > ${TEMP_DIR}/only-attached.csv
comm -3 ${TEMP_DIR}/only-attached.csv ${TEMP_DIR}/no-only-attached.csv | jq -r >${TEMP_DIR}/unattached-policies-list.csv
UNATACHED_POLICIES=$(cat ${TEMP_DIR}/unattached-policies-list.csv | wc -l)
echo Number of Unatached policies: ${UNATACHED_POLICIES}
}
backup_policies() {
cat ${TEMP_DIR}/unattached-policies-list.csv | while read a
do
POLICY_NAME=$(basename $a)
aws iam get-policy --policy-arn $a >${TEMP_DIR}/${POLICY_NAME}.json
done
CREATED_POLICIES=$(ls ${TEMP_DIR}/*.json | wc -l)
echo Backed up Policies: ${CREATED_POLICIES}
}
delete_policy_versions() {
for line in \
$(aws iam list-policy-versions --policy-arn $1 | \
jq -r '.Versions[] | select (.IsDefaultVersion == false) | .VersionId')
do
echo Deleting version: ${line}
aws iam delete-policy-version --policy-arn $1 --version-id ${line}
done
}
delete_policy() {
echo Deleting $1
aws iam delete-policy --policy-arn $1 2>/dev/null
if [ $? != 0 ]
then
# only if standard delete failed we will assume it is because there was many versions so we will delete each version and then retry
delete_policy_versions $1
aws iam delete-policy --policy-arn $1
fi
}
delete_policies() {
confirm "Do you want me to ask confirmation for each policy?"
CONFIRMATION_NEEDED=$?
for a in $(cat ${TEMP_DIR}/unattached-policies-list.csv)
do
echo -e "\n"
if ([ ${CONFIRMATION_NEEDED} == 0 ])
then
echo About to delete: $a
confirm "Do you want to delete this policy?"
if ([ $? == 1 ])
then
echo skipped ...
continue
fi
fi
delete_policy $a
done
}
generate_policy_list
confirm "Do you want to backup all these policies?"
if [ $? == 0 ]; then backup_policies; fi
confirm "Do you want to delete all these policies?"
if [ $? == 0 ]; then delete_policies; fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment