Skip to content

Instantly share code, notes, and snippets.

@chattr
Last active May 8, 2024 08:35
Show Gist options
  • Save chattr/5ab07ebb3b8defc1bb422710eef60a82 to your computer and use it in GitHub Desktop.
Save chattr/5ab07ebb3b8defc1bb422710eef60a82 to your computer and use it in GitHub Desktop.
Auto-configure AWS CLI ~/.aws/config with SSO roles
#!/usr/bin/env bash
#
# Auto-configure AWS CLI ~/.aws/config with SSO roles
#
# Heavily inspired by https://gist.github.com/lukeplausin/3cfedc29755e184ef526b504c77ffe70 👏
#
# Copy and paste "starter" config before running `aws sso login --sso-session login`:
: <<'COMMENT'
[default]
region = us-east-1
output = json
[sso-session login]
sso_start_url = https://d-xxxxxxxxxx.awsapps.com/start
sso_region = us-east-1
sso_registration_scopes = sso:account:access
COMMENT
#
# Begin script
#
set -o nounset -o pipefail
_die() {
# print error to stderr and exit
printf "\nERROR: %s\n" "$1" >&2
exit "${2:-1}"
}
_cleanup() {
rm -f "${tempfile-}"
}
trap _cleanup EXIT
trap _cleanup SIGINT
_check_cmd() {
command -v "$1" > /dev/null 2>&1 || _die "${1} not installed. Aborting."
}
_check_cmd aws
_check_cmd jq
sso_cache="$(jq -s '.[0] * .[1]' ~/.aws/sso/cache/*)"
access_token="$(jq -r '.accessToken' <<< "$sso_cache")" || _die 'No access token found. You may need to aws sso login first.'
start_url="$(jq -r '.startUrl' <<< "$sso_cache")"
region_sso=$(jq -r '.region // "us-east-1"' <<< "$sso_cache")
# default to "$region_sso" if unset or null
: "${assume_role_region:="$region_sso"}"
accounts_data="$(aws sso list-accounts --region "$region_sso" --access-token "$access_token")" || _die 'You may need to aws sso login first.'
accounts_list="$(jq -r '.accountList[].accountId' <<< "$accounts_data")"
tempfile="$(mktemp /tmp/aws_sso.XXXXXX)"
while IFS= read -r account_id; do
account_data="$(jq -r ".accountList | .[] | select( .accountId == \"$account_id\" )" <<< "$accounts_data")"
account_name="$(jq -r '.accountName // .accountId' <<< "$account_data")"
account_roles="$(aws sso list-account-roles --region "$region_sso" --access-token "$access_token" --account-id "$account_id")"
role_names="$(jq -r '.roleList | .[] | .roleName' <<< "$account_roles")"
while read -r role_name; do
config_profile_name="$account_name-$role_name"
if ! grep -q "$config_profile_name" ~/.aws/config; then
cat >> "$tempfile" << EOF
[profile $config_profile_name]
sso_start_url = $start_url
sso_region = $region_sso
sso_account_id = $account_id
sso_role_name = $role_name
sts_regional_endpoints = regional
region = $assume_role_region
EOF
fi
done <<< "$role_names"
done <<< "$accounts_list"
# check if there's config to append to ~/.aws/config
if [[ -s "$tempfile" ]]; then
cat "$tempfile"
printf "\nINFO: %s\n" "The above config will be appended to ~/.aws/config:"
read -r -p "Do want to proceed? [y/n] " yn
case $yn in
[Yy]* ) cat "$tempfile" >> ~/.aws/config; echo "complete!"; ;;
* ) echo "aborted!";;
esac
else
printf "\nINFO: %s\n" "There is no config to append to ~/.aws/config; aborting"
exit 0
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment