Last active
December 4, 2024 15:07
-
-
Save pjaudiomv/65b8fb0875759778083dadbd4be7adbf to your computer and use it in GitHub Desktop.
Get EC2 Assume Role STS Creds and set them locally - useful for testing ec2 role or when you have ssh access to an ec2 but no aws credential accesss
This file contains hidden or 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 | |
# Fetches AWS credentials from a EC2 IAM role and configures them locally for multiple profiles. | |
# Script expects input parameter to be a named Host in your SSH config, then sets AWS creds name using that Host name. | |
# | |
# Configuration | |
# Check for SSH_CONFIG_FILE env var then default to users home dir | |
SSH_CONFIG_FILE="${SSH_CONFIG_FILE:-$HOME/.ssh/config}" | |
readarray -t ssh_hosts < <(grep 'Host ' "$SSH_CONFIG_FILE" | awk '{print $2}' | sort -u) | |
# ANSI color codes for pretty output | |
YELLOW='\033[1;93m' | |
GREEN='\033[1;92m' | |
RED='\033[1;31m' | |
WHITE='\033[1;97m' | |
RESET='\033[0m' | |
# Function to display usage information | |
usage() { | |
echo -e "\n${WHITE}Usage:${RESET} aws-assumerole <ssh-host-1> <ssh-host-2> ... <ssh-host-n>" | |
echo -e "${WHITE}Example:${RESET} aws-assumerole dev-bastion staging-bastion prod-bastion" | |
available_hosts | |
} | |
available_hosts() { | |
echo -e "${YELLOW}Available hosts from ${SSH_CONFIG_FILE}:${RESET}" | |
for host in "${ssh_hosts[@]}"; do | |
echo " $host" | |
done | |
exit 1 | |
} | |
# Function to run curl | |
run_curl() { | |
local SSH_CMD=$1 | |
local TOKEN=$2 | |
local URL=$3 | |
local METHOD="${4:-GET}" | |
local HEADER="${5:-X-aws-ec2-metadata-token: $TOKEN}" | |
TOKEN=$($SSH_CMD "curl -sL -X $METHOD -H \"$HEADER\" http://169.254.169.254/latest$URL") | |
echo "$TOKEN" | |
} | |
# Function to fetch AWS credentials | |
fetch_aws_credentials() { | |
local SSH_CMD="$1" | |
local PROFILE="$2" | |
echo -en "\n${YELLOW}Fetching AWS credentials for $PROFILE${RESET} ." | |
TOKEN=$(run_curl "$SSH_CMD" "" "/api/token" "PUT" "X-aws-ec2-metadata-token-ttl-seconds: 21600") | |
echo -n "." | |
AWS_IAM_ROLE=$(run_curl "$SSH_CMD" "$TOKEN" "/meta-data/iam/security-credentials/") | |
echo -n "." | |
AWS_CREDENTIALS_JSON=$(run_curl "$SSH_CMD" "$TOKEN" "/meta-data/iam/security-credentials/$AWS_IAM_ROLE/") | |
echo -n "." | |
AWS_ACCESS_KEY_ID=$(echo "$AWS_CREDENTIALS_JSON" | jq -r '.AccessKeyId') | |
AWS_SECRET_ACCESS_KEY=$(echo "$AWS_CREDENTIALS_JSON" | jq -r '.SecretAccessKey') | |
AWS_SESSION_TOKEN=$(echo "$AWS_CREDENTIALS_JSON" | jq -r '.Token') | |
AWS_AZ=$(run_curl "$SSH_CMD" "$TOKEN" "/meta-data/placement/availability-zone") | |
echo "." | |
AWS_REGION="${AWS_AZ%?}" | |
echo -e " ${WHITE}AWS_IAM_ROLE:${RESET} $AWS_IAM_ROLE" \ | |
" ${WHITE}AWS_REGION:${RESET} $AWS_REGION" \ | |
" ${WHITE}AWS_AZ:${RESET} $AWS_AZ" | |
aws configure set aws_access_key_id "$AWS_ACCESS_KEY_ID" --profile "$PROFILE" | |
aws configure set aws_secret_access_key "$AWS_SECRET_ACCESS_KEY" --profile "$PROFILE" | |
aws configure set aws_session_token "$AWS_SESSION_TOKEN" --profile "$PROFILE" | |
aws configure set region "$AWS_REGION" --profile "$PROFILE" | |
echo -e "${GREEN}AWS credentials configured for $PROFILE.${RESET}" | |
} | |
# Function to check dependencies | |
check_dependencies() { | |
local dependencies=("jq" "aws") | |
local missing_deps=() | |
for dep in "${dependencies[@]}"; do | |
if ! command -v "$dep" &> /dev/null; then | |
missing_deps+=("$dep") | |
fi | |
done | |
if [ ${#missing_deps[@]} -ne 0 ]; then | |
echo "The following required dependencies are missing:" | |
for dep in "${missing_deps[@]}"; do | |
echo " - $dep" | |
done | |
exit 1 | |
fi | |
} | |
# Function to check valid config | |
check_config() { | |
found=0 | |
for host in "${ssh_hosts[@]}"; do | |
if [[ "$host" == "$1" ]]; then | |
found=1 | |
break | |
fi | |
done | |
# If not found, exit with code 1 | |
if [ "$found" -eq 0 ]; then | |
echo -e "\n${RED}Error:${RESET} Host ${YELLOW}${1}${RESET} not found in SSH config." | |
available_hosts | |
fi | |
} | |
# Main function | |
main() { | |
check_dependencies | |
if [ $# -lt 1 ]; then | |
usage | |
fi | |
for HOST in "$@"; do | |
check_config "$HOST" | |
local SSH_CMD="ssh -F $SSH_CONFIG_FILE $HOST" | |
fetch_aws_credentials "$SSH_CMD" "$HOST" | |
done | |
if [ $# -gt 1 ]; then | |
echo -e "\n${GREEN}All AWS credentials have been configured successfully.${RESET}" | |
fi | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment