Skip to content

Commit

Permalink
Change PROFILE to AWS_PROFILE
Browse files Browse the repository at this point in the history
Support official AWSCLI environment variables AWS_DEFAULT_PROFILE and
AWS_SHARED_CREDENTIALS_FILE.

Use integers and arithmatic for show* variables.

Add short options to README.md
  • Loading branch information
virgilwashere committed Jul 14, 2019
1 parent b7de2c3 commit 6312865
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 92 deletions.
71 changes: 42 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,69 @@

## Fetch AWS keys and secrets from a AWS credentials file

This is a pure bash script that can parse and extract AWS credentials (key id and secret) from a `~/.aws/credentials` file.
This is a pure bash script that can parse and extract AWS credentials (access_key and secret) from a `~/.aws/credentials` file.

```bash
$ ./get-aws-profile.sh --help
Usage: ./get-aws-profile.sh [--credentials=<path>] [--profile=<name>] [--key|--secret|--session-token]
```console
$ get-aws-profile.sh --help
Usage: get-aws-profile.sh [--credentials=<path>] [--profile=<name>] [--key|--secret|--session-token]

Default --credentials is '~/.aws/credentials'
Default --profile is 'default'
Options:
-p, --profile use profile
-f, --credentials read credentials from specified file
-k, --key get value of aws_access_key_id
-s, --secret get value of aws_secret_access_key
-t, --session-token get value of aws_session_token
-h, --help display this help text

By default environment variables are generated, e.g.
source $(./get-aws-profile.sh --profile=myprofile)
Default --credentials is '$AWS_SHARED_CREDENTIALS_FILE' or '~/.aws/credentials'
Default --profile is '$AWS_DEFAULT_PROFILE' or 'default'

To generate environment variables for profile myprofile:

$ source $(get-aws-profile.sh --profile=myprofile)

You can specify one of --key, --secret, --session-token or --expiration to
get just that value, with no line break:

$ FOO_KEY=$(get-aws-profile.sh --profile myprofile --key)
$ FOO_SECRET=$(get-aws-profile.sh -p myprofile -s)
$ FOO_SESSION_TOKEN=$(get-aws-profile.sh -t --profile=myprofile)

You can specify one of --key, --secret, -or --session-token to get just that value, with no line break:
FOO_KEY=$(./get-aws-profile.sh --profile=myprofile --key)
FOO_SECRET=$(./get-aws-profile.sh --profile=myprofile --secret)
FOO_SESSION_TOKEN=$(./get-aws-profile.sh --profile=myprofile --session-token)
```

## Examples

### Set environment variables for 'my-example' profile
### Set AWS environment variables for 'my-example' profile

```bash
$ ./get-aws-profile.sh --profile my-example
```console
$ get-aws-profile.sh --profile=my-example
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

$ eval $(./get-aws-profile.sh --profile my-example)
export AWS_SESSION_TOKEN=IYWKfEIM7SwWerymB0KpQLIKXeE6jBtX1iGKXVqHVEXAMPLETOKEN
$ source $(get-aws-profile.sh --profile=my-example)
```

## Get key and secret for 'my-example' profile
### Get key and secret for 'my-example' profile

```bash
$ ./get-aws-profile.sh --profile my-example --key
```console
$ get-aws-profile.sh --profile=my-example --key
AKIAIOSFODNN7EXAMPLE

$ ./get-aws-profile.sh --profile my-example --secret
$ get-aws-profile.sh --profile=my-example --secret
wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

$ export AWS_ACCESS_KEY_ID=$(./get-aws-profile.sh --profile my-example --key)
$ export AWS_SECRET_ACCESS_KEY=$(./get-aws-profile.sh --profile my-example --secret)
$ export AWS_DEFAULT_PROFILE=my-example
$ export AWS_ACCESS_KEY_ID=$(get-aws-profile.sh --key)
$ export AWS_SESSION_TOKEN=$(get-aws-profile.sh --session-token)
```

## Get key and secret for 'default' profile from a custom 'ini' file
### Get key and secret for 'default' profile from a custom 'ini' file

```bash
$ ./get-aws-profile.sh --credentials /foo/bar/my-creds-file --key
```console
$ get-aws-profile.sh --credentials=/foo/bar/my-creds-file --key
AKIAIOSFODNN7EXAMPLE

$ ./get-aws-profile.sh --credentials /foo/bar/my-creds-file --secret
$ get-aws-profile.sh --credentials=/foo/bar/my-creds-file --secret
wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

Expand All @@ -77,9 +90,9 @@ aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY

I often need to include an AWS key id and secret in deployment scripts. Yet I don't want to actually include the credentials in the script or in the git repository.

Many AWS client tools support storing AWS credentials in the `~/.aws/credentials` file and using a `--profile` argument or `AWS_DEFAULT_PROFILE` environment variable. However other tools only work by setting the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables. Sometimes you need to inject these credentials into stored secrets or configurations.
Many AWS client tools support storing AWS credentials in the `~/.aws/credentials` file and using a `--profile` argument or `AWS_DEFAULT_PROFILE` / `AWS_PROFILE` environment variable. However other tools only work by setting the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables. Sometimes you need to inject these credentials into stored secrets or configurations.

This script helps script these tasks whilst keeping the credentials out of your scripts and repository. I wanted a pure bash solution I could include in automated build and deployment environments.
This script helps automate these tasks whilst keeping the credentials out of your scripts and repository. I wanted a pure bash solution I could include in automated build and deployment environments.

## Credits

Expand Down
157 changes: 94 additions & 63 deletions get-aws-profile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ set -o nounset # Trigger error when expanding unset variables 'set -u'
set -o pipefail # Do not hide errors within pipes 'set -o pipefail'
IFS=$'\n\t'

script_name="${0##*/}"
#
# Fetch the AWS access key and/or secret for an AWS profile
# Fetch the AWS access_key and/or secret from an AWS profile
# stored in the ~/.aws/credentials file ini format
#
# Aaron Roydhouse <[email protected]>, 2017
# https://github.com/whereisaaron/get-aws-profile-bash/
#

#
# cfg_parser - Parse and ini files into variables
Expand All @@ -25,28 +25,25 @@ IFS=$'\n\t'
# http://pastebin.com/f61ef4979 (original)
# http://pastebin.com/m4fe6bdaf (supports spaces in values)
#

# shellcheck disable=SC2206
# shellcheck disable=SC2206,SC2116
cfg_parser ()
{
# IFS=$'\n' && ini=( $(<$1) ) # convert to line-array
mapfile ini <"${1:?Missing INI filename}"
ini=( ${ini[*]//;*/} ) # remove comments ;
ini=( ${ini[*]//\#*/} ) # remove comments #
ini=( ${ini[*]/\ =/=} ) # remove tabs before =
ini=( ${ini[*]/=\ /=} ) # remove tabs be =
ini=( ${ini[*]/\ *=\ /=} ) # remove anything with a space around =
ini=( ${ini[*]/#[/\}$'\n'cfg.section.} ) # set section prefix
ini=( ${ini[*]/%]/ \(} ) # convert text2function (1)
ini=( ${ini[*]/=/=\( } ) # convert item to array
ini=( ${ini[*]/%/ \)} ) # close array parenthesis
ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick
ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2)
ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis
ini[0]="" # remove first element
ini[${#ini[*]} + 1]='}' # add the last brace
# shellcheck disable=SC2116
eval "$(echo "${ini[*]}")" # eval the result
mapfile ini < "${1:?Missing INI filename}" # convert to line-array
ini=(${ini[*]//;*/}) # remove comments ;
ini=(${ini[*]//\#*/}) # remove comments #
ini=(${ini[*]/\ =/=}) # remove tabs before =
ini=(${ini[*]/=\ /=}) # remove tabs be =
ini=(${ini[*]/\ *=\ /=}) # remove anything with a space around =
ini=(${ini[*]/#[/\}$'\n'cfg.section.}) # set section prefix
ini=(${ini[*]/%]/ \(}) # convert text2function (1)
ini=(${ini[*]/=/=\( }) # convert item to array
ini=(${ini[*]/%/ \)}) # close array parenthesis
ini=(${ini[*]/%\\ \)/ \\}) # the multiline trick
ini=(${ini[*]/%\( \)/\(\) \{}) # convert text2function (2)
ini=(${ini[*]/%\} \)/\}}) # remove extra parenthesis
ini[0]="" # remove first element
ini[${#ini[*]} + 1]='}' # add the last brace
eval "$(echo "${ini[*]}")" # eval the result
}

# echo a message to standard error (used for messages not intended
Expand All @@ -56,58 +53,92 @@ echo_stderr ()
printf '%s\n' "$@" >&2
}

#
# Set defaults
# See https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
#
declare AWS_PROFILE CREDENTIALS
declare aws_access_key_id aws_secret_access_key aws_session_token
declare -i show_key show_secret show_session_token

CREDENTIALS="${AWS_SHARED_CREDENTIALS_FILE:-"$HOME/.aws/credentials"}"
AWS_PROFILE=${AWS_PROFILE:-${AWS_DEFAULT_PROFILE:-default}}
show_key=0
show_secret=0
show_session_token=0

#
# Parse options
#

display_usage ()
{
echo_stderr "Usage: $0 [--credentials=<path>] [--profile=<name>] [--key|--secret|--session-token]"
echo_stderr ""
echo_stderr " Default --credentials is '${HOME}/.aws/credentials'"
echo_stderr " Default --profile is 'default'"
echo_stderr ""
echo_stderr " By default environment variables are generated, e.g."
echo_stderr " source \$($0 --profile=${PROFILE:-myprofile})"
echo_stderr ""
echo_stderr " You can specify one of --key, --secret, -or --session-token to get just that value, with no line break:"
echo_stderr " FOO_KEY=\$($0 --profile=${PROFILE:-myprofile} --key)"
echo_stderr " FOO_SECRET=\$($0 --profile=${PROFILE:-myprofile} --secret)"
echo_stderr " FOO_SESSION_TOKEN=\$($0 --profile=${PROFILE:-myprofile} --session-token)"
echo_stderr "Usage: $script_name [--credentials=<path>] [--profile=<name>] [--key|--secret|--session-token]
Options:
-p, --profile use profile
-f, --credentials read credentials from specified file
-k, --key get value of aws_access_key_id
-s, --secret get value of aws_secret_access_key
-t, --session-token get value of aws_session_token
-h, --help display this help text
Default --credentials is '\$AWS_SHARED_CREDENTIALS_FILE' or '~/.aws/credentials'
Default --profile is '\$AWS_DEFAULT_PROFILE' or 'default'
To generate environment variables for profile myprofile:
\$ source \$($script_name --profile=myprofile)
You can specify one of --key, --secret, --session-token or --expiration to
get just that value, with no line break:
\$ FOO_KEY=\$($script_name --profile myprofile --key)
\$ FOO_SECRET=\$($script_name -p myprofile -s)
\$ FOO_SESSION_TOKEN=\$($script_name -t --profile=myprofile)"
}

for i in "$@"
do
case $i in
-c=*|-f=*|--credentials=*)
--credentials=*)
CREDENTIALS="${i#*=}"
shift # past argument=value
;;
-p=*|--profile=*)
PROFILE="${i#*=}"
-f | --credentials)
CREDENTIALS="${2}"
shift 2 # past argument value
;;
--profile=*)
AWS_PROFILE="${i#*=}"
shift # past argument=value
;;
-k|--key)
SHOW_KEY=true
-p | --profile)
AWS_PROFILE="${2}"
shift 2 # past argument value
;;
-k | --key)
show_key=1
shift # past argument with no value
;;
-s|--secret)
SHOW_SECRET=true
-s | --secret)
show_secret=1
shift # past argument with no value
;;
-t|--session-token)
SHOW_SESSION_TOKEN=true
-t | --session-token)
show_session_token=1
shift # past argument with no value
;;
-h*|--h*)
-h | --help)
display_usage
exit 0
exit 64
;;
*)
# unknown option
echo_stderr "Unknown option $1"
echo_stderr "Unknown option $i"
display_usage
exit 1
exit 64
;;
esac
done
Expand All @@ -116,16 +147,10 @@ done
# Check options
#

CREDENTIALS="${CREDENTIALS:-"${HOME}/.aws/credentials"}"
PROFILE=${PROFILE:-default}
SHOW_KEY=${SHOW_KEY:-false}
SHOW_SECRET=${SHOW_SECRET:-false}
SHOW_SESSION_TOKEN=${SHOW_SESSION_TOKEN:-false}

if [[ "${SHOW_KEY}" = true && "${SHOW_SECRET}" = true ]]; then
echo_stderr "Can only specify one of --key or --secret"
if [[ $((show_key + show_secret + show_session_token)) -gt 1 ]]; then
echo_stderr "Can only specify one of --key,--secret or --session-token"
display_usage
exit 2
exit 64
fi

#
Expand All @@ -142,26 +167,32 @@ if ! cfg_parser "${CREDENTIALS}"; then
exit 4
fi

if ! cfg.section."${PROFILE}" >/dev/null; then
echo_stderr "Profile '${PROFILE}' not found"
if ! cfg.section."${AWS_PROFILE}" 2> /dev/null; then
echo_stderr "Profile '${AWS_PROFILE}' not found"
exit 5
fi

# shellcheck disable=SC2154
if [[ "${SHOW_KEY}" = false && "${SHOW_SECRET}" = false && "${SHOW_SESSION_TOKEN}" = false ]]; then
echo_stderr "# Profile: ${PROFILE}"
if ! ((show_key + show_secret + show_session_token)); then
echo_stderr "# Profile '${AWS_PROFILE}'"
printf 'export AWS_ACCESS_KEY_ID=%s\n' "${aws_access_key_id}"
printf 'export AWS_SECRET_ACCESS_KEY=%s\n' "${aws_secret_access_key}"
printf 'export AWS_SESSION_TOKEN=%s\n' "${aws_session_token}"
elif [[ "${SHOW_KEY}" = true ]]; then
elif ((show_key)); then
printf '%s' "${aws_access_key_id}"
elif [[ "${SHOW_SECRET}" = true ]]; then
elif ((show_secret)); then
printf '%s' "${aws_secret_access_key}"
elif [[ "${SHOW_SESSION_TOKEN}" = true ]]; then
elif ((show_session_token)); then
printf '%s' "${aws_session_token}"
else
echo_stderr "Unknown error"
exit 9
fi

unset -v CREDENTIALS
unset -v show_key show_secret show_session_token
unset -v aws_access_key_id aws_secret_access_key aws_session_token

exit 0

# vim: tabstop=2 shiftwidth=2 expandtab filetype=sh syntax=sh

0 comments on commit 6312865

Please sign in to comment.