Skip to content

Instantly share code, notes, and snippets.

@kapcod
Last active August 22, 2022 07:13
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 kapcod/2c1b91835cd5d44915ac1b29379f3661 to your computer and use it in GitHub Desktop.
Save kapcod/2c1b91835cd5d44915ac1b29379f3661 to your computer and use it in GitHub Desktop.
Bash script to run any command in assumed AWS role, requires aws-cli, tested on aws-cli 2, includes caching for 12 hours
#!/bin/bash -e
usage(){
cat <<'HELP'
Usage: aws-assume-role <base-profile> <mfa-ARN> <role-ARN> <session-name> [<command>...]
This script is designed to be used from alias like this (of course you can also call it from other scripts):
alias assume-admin-prod='/path/to/aws-assume-role bob arn:aws:iam::1234567:mfa/bob arn:aws:iam::321321321:role/admin bob'
Arguments are positional and not key-word options on purpose. You just copy-paste it into .bash_profile to create alias and replace the parameters with right values.
<base-profile> is needed in case your default profile already includes role switch, in this case 'sts assume-role' won't work.
<session-name> can be any string which will later appear in AWS CloudTrail logs. Usually it mostly makes most sense to use your user-name.
Currently the duration is hard-coded to the maximum allowed - 12 hours, if some role forces reduced session duration, please alter the code
If you want export the session in the current terminal, just do: `export $(aws-assume-role ...)` or run without command and copy-paste the output
HELP
}
if [[ -z "$1" ]]; then
usage
exit
fi
BASE_PROFILE=$1
SERIAL=$2
ROLE_ARN=$3
SESSION_NAME=$4
shift 4
DURATION=43200
CACHE="$HOME/.aws-assume-role/cache"
mkdir -p "$CACHE"
find "$CACHE" -type f -mtime +${DURATION}s -delete
role_hash=$(echo "$SERIAL:$ROLE_ARN" | md5)
cache_file="$CACHE/$role_hash"
if [[ -f "$cache_file" ]]; then
res=$(cat "$cache_file")
else
echo -n "MFA token for $SERIAL: "
read token
[[ -n $token ]] || exit 1
res=$(aws sts assume-role --profile "$BASE_PROFILE" --serial-number "$SERIAL" --role-arn "$ROLE_ARN" --role-session-name "$SESSION_NAME" --token-code "$token" --duration-seconds $DURATION --output json)
echo "$res" > "$cache_file"
echo "Successfully assumed and cached role, expiration: $(echo "$res" | jq '.Credentials.Expiration')"
fi
exp_vars="AWS_ACCESS_KEY_ID=$(echo "$res" | jq -r '.Credentials.AccessKeyId')
AWS_SECRET_ACCESS_KEY=$(echo "$res" | jq -r '.Credentials.SecretAccessKey')
AWS_SESSION_TOKEN=$(echo "$res" | jq -r '.Credentials.SessionToken')"
if [[ -n $1 ]]; then
env -S "$exp_vars" "$@"
else
echo "$exp_vars"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment