Skip to content

Instantly share code, notes, and snippets.

@asvinours
Last active March 15, 2024 19:28
Show Gist options
  • Save asvinours/0e6e99381306b12c94d34ec102fb80ed to your computer and use it in GitHub Desktop.
Save asvinours/0e6e99381306b12c94d34ec102fb80ed to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -eEo pipefail
verify_mfa_arn () {
local MFA_ARN="$1"
if [ -z "$MFA_ARN" ];
then
echo "You need to configure your MFA device for '$AWS_CLI_PROFILE' profile"
read -p "Enter the ARN of your MFA device: " MFA_ARN
aws --profile "$AWS_CLI_PROFILE" configure set mfa_serial "$MFA_ARN"
fi
}
AWS_CLI_PROFILE="default"
while getopts 'yt:p:' opt; do
case "$opt" in
p )
AWS_CLI_PROFILE="$OPTARG"
;;
y )
YUBICO="true"
echo "Yubico hardware key mode activated..."
;;
--) shift;
break
;;
esac
done
shift "$(($OPTIND -1))"
######################
### Verify the AWS CLI tool is installed locally
AWS_CLI=`which aws`
if [ $? -ne 0 ];
then
echo "AWS CLI is not installed; exiting"
exit 1
else
echo "Using AWS CLI found at $AWS_CLI"
fi
######################
### Checking if aws cli has been properly configured already
echo "Reading config..."
if [ ! -r ~/.aws/config ];
then
echo "You have not configured your AWS CLI yet."
echo "Let's do this now"
aws --profile "$AWS_CLI_PROFILE" configure
fi
######################
### Retrieving ARN of MFA device from aws config file
### If no MFA device configured, ask user to input
### the ARN of their MFA device
if [[ "${YUBICO,,}" == "true" ]];
then
set +e
MFA_ARN=$(aws --profile "$AWS_CLI_PROFILE" configure get mfa_serial_yubico || aws --profile "$AWS_CLI_PROFILE" configure get mfa_serial)
set -e
verify_mfa_arn "$MFA_ARN"
TOTP_CODE=$(ykman oath accounts code $MFA_ARN | awk '{ print $NF}')
else
set +e
MFA_ARN=$(aws --profile "$AWS_CLI_PROFILE" configure get mfa_serial)
set -e
verify_mfa_arn "$MFA_ARN"
read -p "Enter the TOTP 6 digits code: " TOTP_CODE
fi
AWS_CLI_MFA_PROFILE="${AWS_CLI_PROFILE}_mfa"
echo "AWS-CLI profile: '${AWS_CLI_PROFILE}'"
echo "AWS-CLI MFA profile: '${AWS_CLI_MFA_PROFILE}'"
echo "MFA ARN: '${MFA_ARN}'"
######################
### Retrieving session token from AWS STS service
### See https://docs.aws.amazon.com/cli/latest/reference/sts/get-session-token.html
(( TOKEN_VALIDITY = 3600 * 12 ))
if [ -n "$AWS_ACCESS_KEY_ID" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ];
then
STS_OUTPUT=$(aws sts get-session-token \
--duration-seconds "$TOKEN_VALIDITY" \
--serial-number "$MFA_ARN" --token-code "$TOTP_CODE" \
--query 'Credentials' --output text)
else
STS_OUTPUT=$(aws --profile "$AWS_CLI_PROFILE" sts get-session-token \
--duration-seconds "$TOKEN_VALIDITY" \
--serial-number "$MFA_ARN" --token-code "$TOTP_CODE" \
--query 'Credentials' --output text)
fi
######################
### AWS CLI output is TSV, so we need to split the one line
### into multiple variables
AWS_ACCESS_KEY_ID=$(echo "$STS_OUTPUT" | awk '{ print $1 }')
AWS_SECRET_ACCESS_KEY=$(echo "$STS_OUTPUT" | awk '{ print $3 }')
AWS_SESSION_TOKEN=$(echo "$STS_OUTPUT" | awk '{ print $4 }')
######################
### Create new profile with "_mfa" suffix
### and set temporary credentials for that profile
aws --profile "$AWS_CLI_MFA_PROFILE" configure set aws_access_key_id "$AWS_ACCESS_KEY_ID"
aws --profile "$AWS_CLI_MFA_PROFILE" configure set aws_secret_access_key "$AWS_SECRET_ACCESS_KEY"
aws --profile "$AWS_CLI_MFA_PROFILE" configure set aws_session_token "$AWS_SESSION_TOKEN"
if [[ "$AWS_PROFILE" == "$AWS_CLI_MFA_PROFILE" ]];
then
echo "All good!"
else
echo "You can now use the new MFA profile: ${AWS_CLI_MFA_PROFILE}"
echo ""
echo -e "Run: \033[1mexport AWS_PROFILE='${AWS_CLI_MFA_PROFILE}'\033[0m"
echo -e "Or add \033[1mexport AWS_PROFILE='${AWS_CLI_MFA_PROFILE}'\033[0m to your ~/.bashrc file"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment