Created
March 23, 2018 13:23
-
-
Save dataday/c32d1206da42b60942181430d7665a66 to your computer and use it in GitHub Desktop.
A wrapper to assume a specified role via AWS Security Token Service (STS)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
## A wrapper to assume a specified role via AWS Security Token Service (STS) | |
# | |
# Access to some AWS services can require specific role privileges in order to work | |
# The script requests and returns the AWS credentials needed to perform certain tasks by assuming a specified role | |
# The script interacts with AWS Security Token Service (STS) in order to assume the desired role | |
# | |
# The following command could be used if you wanted to assume the JenkinsAutomationRole to query AWS services | |
# Please note not all options are required as it will depend on the environment the script is invoked against | |
# | |
# $ assume_role.sh --project=nswws --env=stg --region=eu-west-2 --role=JenkinsAutomationRole --output=json | |
# | |
# Exports via --output=env: | |
# AWS_ACCESS_KEY_ID=*, AWS_SECRET_ACCESS_KEY=*, AWS_SESSION_TOKEN=* | |
# | |
# Returns via --output=json: | |
# {"AWS_ACCESS_KEY_ID": "*", "AWS_SECRET_ACCESS_KEY": "*", "AWS_SESSION_TOKEN": "*"} | |
# | |
## | |
EXEC=$(realpath -L "${0#./}") | |
EXEC_BASE="${EXEC%/*}" | |
EXEC_NAME=$(basename "$EXEC") | |
# set defaults | |
PROJECT_REGION="eu-west-2" | |
PROJECT_NAME="nswws" | |
PROJECT_ENVIRONMENT="stg" | |
PROJECT_ROLE="JenkinsAutomationRole" | |
declare -a AWS_ACCOUNTS | |
AWS_OUTPUT="env" | |
AWS_ACCOUNTS=(["stg"]="" ["dev"]="" ["prd"]="") | |
AWS_SESSION_TIMEOUT=3600 | |
# displays usage information | |
function usage () { | |
printf %s "Usage: $EXEC_NAME [--region=REGION --project=PROJECT --env=ENV --role=ROLE --output=(json|env)] | |
A wrapper to AWS assume role services | |
Options: | |
--region - AWS region, default: eu-west-2 | |
--project - Project name, default: nswws | |
--env - Project environment, default: stg | |
--role - Project Role, default: JenkinsAutomationRole | |
--output - Specified output type (env|json), default: env | |
" 1>&2 | |
exit $? | |
} | |
# checks for options | |
if (($# == 0)); then | |
usage | |
fi | |
# assumes specified role via the AWS Security Token Service (STS) | |
function assume_role () { | |
# print without line breaks and search and replace single quotes for double | |
local json="$(printf %s ${1//\'/\"})" | |
# confirm the OS the script is running under (detects quasi-unix under windows) | |
[[ `uname` = "MINGW64"* ]] && exec="aws.cmd" || exec="aws" | |
# calls AWS Security Token Service (STS) to assume a specified role | |
printf %s $("$exec" sts assume-role --region "$PROJECT_REGION" --cli-input-json "$json") | |
} | |
# gets credentials information from the AWS assume role response | |
function get_credential () { | |
local exec=$(which python) | |
# ensure exports of credential data are kept private during execution | |
printf %s $( | |
export KEY="$1" | |
export VAL="$2" | |
"$exec" -c "import json,os;k=os.environ['KEY'];v=os.environ['VAL'];obj=json.loads(v);res=obj.get('Credentials');print(res.get(k,''))" | |
) | |
} | |
# assigns supported options | |
while getopts ":-:" opt; do | |
case "$opt" in | |
-) | |
case $OPTARG in | |
region=*) PROJECT_REGION="${OPTARG#*=}";; | |
project=*) PROJECT_NAME="${OPTARG#*=}";; | |
env=*) PROJECT_ENVIRONMENT="${OPTARG#*=}";; | |
role=*) PROJECT_ROLE="${OPTARG#*=}";; | |
output=*) AWS_OUTPUT="${OPTARG#*=}";; | |
esac | |
;; | |
\?) log "error: -$OPTARG" && usage;; | |
*) usage;; | |
esac | |
done | |
# initiate | |
function init () { | |
AWS_ACCOUNT="${AWS_ACCOUNTS[$ENVIRONMENT]}" | |
AWS_INPUT="{ | |
'RoleArn': 'arn:aws:iam::$AWS_ACCOUNT:role/$PROJECT_ROLE', | |
'RoleSessionName': 'jenkins-$(date +%s)', | |
'DurationSeconds': $AWS_SESSION_TIMEOUT | |
}" | |
# executes AWS CLI request to assume a specified role | |
local credentials=$(assume_role "$AWS_INPUT") | |
if [[ -n "$credentials" ]]; then | |
# assigns AWS specific credentials | |
local ACCESS_KEY_ID=$(get_credential "AccessKeyId" "$credentials") | |
local SECRET_ACCESS_KEY=$(get_credential "SecretAccessKey" "$credentials") | |
local SESSION_TOKEN=$(get_credential "SessionToken" "$credentials") | |
case "$AWS_OUTPUT" in | |
# exports AWS specific environment variables | |
"env") | |
export AWS_ACCESS_KEY_ID="$ACCESS_KEY_ID" | |
export AWS_SECRET_ACCESS_KEY="$SECRET_ACCESS_KEY" | |
export AWS_SESSION_TOKEN="$SESSION_TOKEN" | |
;; | |
# prints JSON formatted credentials | |
"json") | |
local json="{ | |
'AWS_ACCESS_KEY_ID': '$ACCESS_KEY_ID', | |
'AWS_SECRET_ACCESS_KEY': '$SECRET_ACCESS_KEY', | |
'AWS_SESSION_TOKEN': '$SESSION_TOKEN' | |
}" | |
# print without line breaks and search and replace single quotes for double | |
printf %s ${json//\'/\"} | |
;; | |
# default | |
*) | |
printf %s "error: unsupported output $AWS_OUTPUT" | |
exit 1 | |
esac | |
fi | |
} | |
init | |
exit $? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment