Skip to content

Instantly share code, notes, and snippets.

@avoidik
Forked from brianredbeard/get_token.md
Created June 21, 2019 10:46
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 avoidik/7513d94895331ba2487a70bd704f0395 to your computer and use it in GitHub Desktop.
Save avoidik/7513d94895331ba2487a70bd704f0395 to your computer and use it in GitHub Desktop.
aws, sts, and bash

About

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.

Explanation

Below is an overexplained version of the following process:

  1. Using credentials stored in ~/.aws/credentials as a "profile" which are then understood by the AWS command line tools
  2. 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
  3. 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
  4. 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.
  5. 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 the aws 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

Copy Paste Version:

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) "')

To unset these values:

Manual Command

source <(env | awk -F= '/AWS/ {print "unset ", $1}')

BASH Alias

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} \')'

Links

sub: http://wiki.bash-hackers.org/syntax/expansion/proc_subst

pipe: http://wiki.bash-hackers.org/syntax/basicgrammar#pipelines

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment