Ghetto AWS profile switcher

All problems in computer science can be solved by another level of indirection, except for the problem of too many levels of indirection. — Kevlin Henney

I have three sets of AWS credentials: two for work and one for personal projects. In the absence of a tool for managing AWS profiles, I cobbled a solution together using symlinks and bash functions.

My implementation of a profile is a symlink to a credentials file, which defines a pair of AWS access keys and by convention lives at ~/.aws/credentials. I keep the various sets of credentials in ~/.aws/profiles.d:

~ $ ls ~/.aws/profiles.d
99designs       personal        workbench

~ $ readlink ~/.aws/credentials
/Users/stuart/.aws/profiles.d/workbench

Here's some bash to manage the symlinking:

PROFILES_DIR="$HOME/.aws/profiles.d"
CREDENTIALS="$HOME/.aws/credentials"

aws-profile() { local profile="$1"

if [[ -z $profile ]]; then _aws-profile-usage >&2 else _aws-switch-profile $profile fi }

__aws-profile-usage() { echo "usage: aws-profile <profile>

Available profiles: $(for profile in $(aws-ls-profiles | sort); do if [[ $profile == $(aws-active-profile) ]]; then echo -n " * " else echo -n " - " fi echo $profile done)" }

__aws-active-profile() { basename $(readlink "$CREDENTIALS") }

_aws-switch-profile() { local profilename="$1" local profilecredentials="$PROFILESDIR/$profile_name"

if [[ ! -f "$profilecredentials" ]]; then echo "profile $profilename not found" >&2 return 1 fi

ln -fhs "$profilecredentials" "$CREDENTIALS" echo "profile $profilename activated" }

_aws-ls-profiles() { ls -1 "$PROFILESDIR" | xargs -n1 basename }

aws-profile-completion() { local input="${COMPWORDS[COMPCWORD]}" local candidates="$(aws-ls-profiles | sort)" COMPREPLY=($(compgen -W "$candidates" -- $input)) }

complete -F __aws-profile-completion aws-profile

And here's how I use it:

~ $ aws-profile
usage: aws-profile <profile>

Available profiles:
 - 99designs
 - personal
 - workbench *

~ $ aws-profile personal
profile personal activated

Note: since I initially wrote this stuff, my colleague implemented something much better for OS X.