At my current job, I have a need to be access multiple AWS accounts. Generally we follow the AWS best practices for security and set up IAM accounts with restricted functionality that can access only the resources that are appropriate for the completion of the task at hand. At this point we've looked at federation technologies (such as SAML), but haven't yet implemented this.
Generally, I like to make sure that whatever I do using the AWS console on the web I can also achieve using the AWS cli (which is now based on boto, it appears they have phase out the Java based CLI). So I tend to at least document what equivalent AWS CLI commands are for whatever functionality I'm working on. However, I have multiple AWS API keys, depending on what I am working on and which account the work is associated with. So, those keys are associated with different AWS accounts, e.g. when using an AWS lab in a class, I might end up with access keys for that class, which I can use during the lab.
The AWS environment provides quite a convenient setup for this, using configuration files in your ~/.aws directory. They also allow you to use a ~/.awsrc file, which I use for my autocompletion.
So, I've set up a directory with a set of config files, named awscfg-whatever.cfg containing the key and secrets for the various accounts, as follows:
ls -l ~/.awsrc ~/.aws lrwxrwxrwx. 1 vmic vmic 22 Apr 4 09:21 /home/vmic/.awsrc > .aws/awsrc-es-vmic.cfg -rw-------. 1 vmic vmic 75 Jun 11 2014 awsrc-account1.cfg -rw-------. 1 vmic vmic 75 Nov 25 2014 awsrc-es-vmic.cfg -rw-------. 1 vmic vmic 75 May 27 2015 awsrc-qwiklab.cfg lrwxrwxrwx. 1 vmic vmic 9 May 5 2015 config > config-es -rw-------. 1 vmic vmic 203 May 7 2015 config-es # cat ~/.aws/awsrc-qwiklab.cfg key AKIAJSP5SAXQHBUVQYLA password sv5RTXCRrd4YFgGvdbbdM52GMttXa3X_xN.J4gww
The config file just contains the various defaults I want to use, such as the region. I haven't included this in the switching process, though I could add that.
What this allows me to do is to write a simple bash auto-completion script that look in the ~/.aws directory and enumerates all the files with the pattern awsrc-*.cfg. And then I can simply use that information to link the specified file to the ~/.awsrc file, resulting in the AWS CLI using a different account:
# switch-aws current config: es-vmic configs: account1 es-vmic qwiklab # switch-aws qwiklab switched to qwikab # ls -l ~/.awsrc lrwxrwxrwx. 1 vmic vmic 22 Apr 6 10:19 /home/vmic/.awsrc > .aws/awsrc-qwiklab.cfg
And if you have multiple accounts starting with the same name, the autocompletion script will show what options there are for switching.
It's worth noting that the AWS cli comes with it's own autocompletion script written in python that works quite amazingly.
The two scripts involved are:
switch-aws
#!/bin/bash # # A simple bash shell script to setup AWS environments. The # idea is to have a a number of aws configurations in ~/.aws # (with appropriate file permissions) using a standard nameing # convention 'awsrc-*.cfg'. This script simply finds those and # sets up the environment variables for use by both the CLI and # the command tools. Please note that the CLI and the command # line tools use different environment variables (what!?). Also # note that the CLI has more extensive configurations that can be # configured in a ~/.aws/config file which I do not address here. # # I also have a small bash autocompletion script which will # allow me to use 'switch-aws' to show all configured AWS # configurations. # AWS_LOC="$HOME/.aws" CONFIGS= get_cfgs () { if [ -z "$CONFIGS" ]; then l=`/bin/ls -1 $AWS_LOC/awsrc-*.cfg` for f in $l; do f=${f##*/awsrc-} f=${f%.cfg} CONFIGS="$CONFIGS $f" done fi } list_cfgs () { get_cfgs echo "configs:" for f in $CONFIGS; do echo " $f" done } list_current_cfg () { if [ -h "$HOME/.awsrc" ]; then f=`readlink "$HOME/.awsrc"` f=${f##*/awsrc-} f=${f%.cfg} echo "current config: $f" else echo "no current config" fi } set_cfg () { get_cfgs for f in $CONFIGS; do if [ "$f" == "$1" ]; then rm -f "$HOME/.awsrc" /bin/ln -s ".aws/awsrc-${f}.cfg" "$HOME/.awsrc" echo "switched to $f" return 0 fi done echo "no config called $1" } set_env () { k=`/bin/egrep "^key " "$HOME/.awsrc" | awk '{print $2}'` export AWS_ACCESS_KEY="$k" export AWS_ACCESS_KEY_ID="$k" p=`/bin/egrep "^password " "$HOME/.awsrc" | awk '{print $2}'` export AWS_SECRET_KEY="$p" export AWS_SECRET_ACCESS_KEY="$p" } if [ "$#" -ne "1" ]; then list_current_cfg list_cfgs else set_cfg $1 set_env fi
switch-aws_completion
#!/bin/bash function _awsrc_completion_() { local word=${COMP_WORDS[COMP_CWORD]} local aws_loc="$HOME/.aws" local l l=`/bin/ls -1 $aws_loc/awsrc-${word}*.cfg 2>/dev/null` for f in $l; do f=${f##*/awsrc-} f=${f%.cfg} COMPREPLY+=($f) done } complete -F _awsrc_completion_ switch-aws
And you need to include alias switch-aws=". script-location/switch-aws" in your .bashrc somewhere as well as running the autocompletion script out of your .bashrc.