-
-
Save skehlet/8e32eb68658c452b8c51342898936e9f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Wrapper for any AWS-related command using aws that handles the 1 hour MFA token. | |
# | |
# Create an aws-role.config.json file in the same directory as this script that looks like: | |
# { | |
# "<your-profile-nickname>": { | |
# "profile": "<your-hub>", | |
# "region": "<your-default-region>", | |
# "mfa_arn": "<your-mfa-arn>", | |
# "role_arn": "<your-assume-role-arn>" | |
# } | |
# } | |
# | |
# Also update your ~/.aws/config and ~/.aws/credentials with a "<your-hub>" profile: | |
# | |
# ~/.aws/config: | |
# [profile <your-hub>] | |
# region = <your-default-region> | |
# | |
# ~/.aws/credentials: | |
# [<your-hub>] | |
# aws_access_key_id = <your-hub-access-key-id> | |
# aws_secret_access_key = <your-hub-secret-access-key> | |
# | |
# You can either run this script and provide the account name as the first argument, | |
# or you can make a symlink using the account name to this script. | |
# | |
set -e | |
unset AWS_ACCESS_KEY_ID | |
unset AWS_SECRET_ACCESS_KEY | |
unset AWS_SESSION_TOKEN | |
unset AWS_DEFAULT_REGION | |
unset AWS_DEFAULT_OUTPUT | |
unset AWS_PROFILE | |
unset AWS_CA_BUNDLE | |
unset AWS_SHARED_CREDENTIALS_FILE | |
unset AWS_CONFIG_FILE | |
my_name=$(basename $0) | |
if [[ $my_name != "aws-role" ]]; then | |
account=$my_name | |
else | |
account=$1 | |
shift | |
fi | |
config=$(dirname $0)/aws-role.config.json | |
session_token_credentials=~/.aws/.aws-role.session-token.${account} | |
assume_role_credentials=~/.aws/.aws-role.assume-role.${account} | |
MAX_SESSION_TOKEN_CREDENTIALS_AGE=$(( 129600 - 60 )) | |
MAX_ASSUME_ROLE_CREDENTIALS_AGE=$(( 1800 )) # half hour, assuming any reasonable aws-related commands (looking at you terraform) will finish in less than 1/2 hour | |
TMPFILE1= | |
TMPFILE2= | |
cleanup() { | |
[[ -n $TMPFILE1 ]] && rm -f $TMPFILE1 | |
[[ -n $TMPFILE2 ]] && rm -f $TMPFILE2 | |
} | |
trap cleanup EXIT | |
now=$(date +%s) | |
if ! aws_profile=$(jq -r ".\"${account}\".profile" < $config) \ | |
|| ! aws_default_region=$(jq -r ".\"${account}\".region" < $config) \ | |
|| ! mfa_arn=$(jq -r ".\"${account}\".mfa_arn" < $config) \ | |
|| ! role_arn=$(jq -r ".\"${account}\".role_arn" < $config) | |
then | |
echo "Missing or incomplete config for account $account. Please update your $config" | |
exit 1 | |
fi | |
file_age() { | |
case "$(uname)" in | |
Darwin) stat -t %s -f %m -- "$1" 2>/dev/null ;; | |
Linux) date +%s -r "$1" 2>/dev/null ;; | |
*) echo "unknown platform"; exit 1 ;; | |
esac | |
} | |
if [[ $(( $(file_age $session_token_credentials) + $MAX_SESSION_TOKEN_CREDENTIALS_AGE)) -lt $now ]]; then | |
TMPFILE1=$(mktemp) | |
read -p "MFA code: " code | |
env \ | |
AWS_PROFILE=$aws_profile \ | |
AWS_DEFAULT_REGION=$aws_default_region \ | |
aws sts get-session-token \ | |
--serial-number "$mfa_arn" \ | |
--token-code "$code" \ | |
--duration-seconds 129600 \ | |
> $TMPFILE1 | |
aws_access_key_id=$(jq -r '.Credentials.AccessKeyId' < $TMPFILE1) | |
aws_secret_access_key=$(jq -r '.Credentials.SecretAccessKey' < $TMPFILE1) | |
aws_session_token=$(jq -r '.Credentials.SessionToken' < $TMPFILE1) | |
cat > $session_token_credentials <<EOF | |
export AWS_ACCESS_KEY_ID=$aws_access_key_id | |
export AWS_SECRET_ACCESS_KEY=$aws_secret_access_key | |
export AWS_SESSION_TOKEN=$aws_session_token | |
export AWS_DEFAULT_REGION=$aws_default_region | |
EOF | |
fi | |
source $session_token_credentials | |
if [[ $(( $(file_age $assume_role_credentials) + $MAX_ASSUME_ROLE_CREDENTIALS_AGE)) -lt $now ]]; then | |
TMPFILE2=$(mktemp) | |
aws sts assume-role \ | |
--role-arn $role_arn \ | |
--role-session-name $now \ | |
> $TMPFILE2 | |
aws_access_key_id=$(jq -r '.Credentials.AccessKeyId' < $TMPFILE2) | |
aws_secret_access_key=$(jq -r '.Credentials.SecretAccessKey' < $TMPFILE2) | |
aws_session_token=$(jq -r '.Credentials.SessionToken' < $TMPFILE2) | |
cat > $assume_role_credentials <<EOF | |
export AWS_ACCESS_KEY_ID=$aws_access_key_id | |
export AWS_SECRET_ACCESS_KEY=$aws_secret_access_key | |
export AWS_SESSION_TOKEN=$aws_session_token | |
export AWS_DEFAULT_REGION=$aws_default_region | |
EOF | |
fi | |
source $assume_role_credentials | |
exec "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment