AWS provides a mechanism for temporarily assuming another role within their API system. While it is not a technically hard process it can be convoluted and hard to understand. This document aims to both make it easier to follow along with as well as give an in depth explanation of some of the underpinnings of the Bourne Again Shell (aka BASH) which can make this easier to utilize on a day to day basis.
Below is an overexplained version of the following process:
- Using credentials stored in
~/.aws/credentials
as a "profile" which are then understood by the AWS command line tools - Using those AWS credentials, temporarily assume a role using the AWS Security Token Service (STS) to get temporary credentials corresponding to a role in another account
- Taking the JSON output of that AWS STS API response and parsing out the relevant values to create a series of Bourne Again Shell (bash) commands to provide access to the role via the AWS CLI commands
- Placing the generated bash commands into a temporary file using a "first in first out special file" (FIFO, also
known as a "named pipe"). We are doing this because the subsequent command (
source
) cannot take input via a pipeline and should use a file argument. - Read and execute the commands from the temporary file descriptor in our current environment, thus exporting the
following variables, which (similar to
AWS_PROFILE
are understood by the underlying libraries used by theaws
command):AWS_SESSION_TOKEN
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
Using process substitution[sub] create a temporary file descriptor which will hold the output of our "aws" command then pipelined[pipe] through jq
----------------------------------------------------------------------------------------------------------------------------------------------------------------
| |
| AWS Profile from Target Name of the role to assume Friendly |
| ~/.aws/credentials Account # in the target account # Name |
| ------------------ ---------- ---------------------------- --------- |
| | | | | | | | | |
source <(AWS_PROFILE=redbeard aws sts assume-role --role-arn arn:aws:iam::123456789123:role/OrganizationAccountAccessRole --role-session-name "DevAccount" | \ |
jq -r '.Credentials | @sh "export AWS_SESSION_TOKEN=\(.SessionToken)\nexport AWS_ACCESS_KEY_ID=\(.AccessKeyId)\nexport AWS_SECRET_ACCESS_KEY=\(.SecretAccessKey) "')
After this has occurred you will have received a set of temporary credentials what are good for one hour, one can validate this using the command echo $AWS_ACCESS_KEY_ID
. Due to the nature of STS tokens, it should be different each time you acquire one
source <(AWS_PROFILE=redbeard aws sts assume-role --role-arn arn:aws:iam::123456789123:role/OrganizationAccountAccessRole --role-session-name "DevAccount" | jq -r '.Credentials | @sh "export AWS_SESSION_TOKEN=\(.SessionToken)\nexport AWS_ACCESS_KEY_ID=\(.AccessKeyId)\nexport AWS_SECRET_ACCESS_KEY=\(.SecretAccessKey) "')
source <(env | awk -F= '/AWS/ {print "unset ", $1}')
What follows is a BASH alias which can be added to .bash_profile
. Once in place, using the alias UNSET_AWS
will unset all AWS environment variables. This uses a special quoting syntax which allows for the use of backslash escaped characters as per the ANSI C standard (see the QUOTING
section of man 1 bash
for more details).
alias UNSET_AWS=$'source <(env | awk -F= \' /AWS/ {print "unset ", $1} \')'
sub: http://wiki.bash-hackers.org/syntax/expansion/proc_subst
pipe: http://wiki.bash-hackers.org/syntax/basicgrammar#pipelines
I wrote a small Python tool called
sts2env
: https://gist.github.com/russellballestrini/bfae477ef36b36e8803fb4a2d241fc78Usage:
eval $(aws sts assume-role --role-arn arn:aws:iam::01234:role/the-role-name --role-session-name my-role-session | ./sts2env)