Last active
April 18, 2025 06:40
-
-
Save huynhbaoan/14784a299684f8fe58d55e97f6e96c71 to your computer and use it in GitHub Desktop.
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 zsh | |
# aws-multi-role.zsh | |
# Usage: ./aws-multi-role.zsh <env> | |
# Example: ./aws-multi-role.zsh preprod | |
set -euo pipefail | |
# --- 1. prerequisites -------------------------------------------------------- | |
# verify jq is installed (for JSON parsing) | |
if ! command -v jq >/dev/null; then | |
echo "ERROR: this script requires 'jq'. Please install it and retry." >&2 | |
exit 1 | |
fi | |
# --- 2. mappings ------------------------------------------------------------- | |
# env → source-profile name in ~/.aws/credentials | |
typeset -A ENV2PROFILE CSVFILE | |
ENV2PROFILE=( | |
dev servicesdev | |
test servicestest | |
np servicesnp | |
preprod servicespreprod | |
prod servicesprod | |
) | |
CSVFILE=( | |
dev dev.csv | |
test test.csv | |
np np.csv | |
preprod preprod.csv | |
prod prod.csv | |
) | |
# --- 3. parse & validate input ---------------------------------------------- | |
if (( $# != 1 )); then | |
echo "Usage: $0 <environment: dev|test|np|preprod|prod>" >&2 | |
exit 1 | |
fi | |
env=$1 | |
src_profile=${ENV2PROFILE[$env]:-} | |
csv_file=${CSVFILE[$env]:-} | |
if [[ -z $src_profile ]]; then | |
echo "ERROR: invalid environment '$env'." >&2 | |
exit 1 | |
fi | |
if [[ ! -f $csv_file ]]; then | |
echo "ERROR: CSV file '$csv_file' not found for environment '$env'." >&2 | |
exit 1 | |
fi | |
echo "→ using source profile: [$src_profile]" | |
echo "→ reading accounts from: $csv_file" | |
# --- 4. test source credentials --------------------------------------------- | |
if ! aws sts get-caller-identity --profile "$src_profile" &>/dev/null; then | |
echo "ERROR: credentials for profile '$src_profile' are invalid or expired." >&2 | |
exit 1 | |
fi | |
echo "✔ source credentials are valid." | |
# --- 5. detect original role type ------------------------------------------- | |
# read the role_arn from your AWS config (not credentials) for this profile | |
orig_role_arn=$(aws configure get role_arn --profile "$src_profile" || true) | |
if [[ -z $orig_role_arn ]]; then | |
echo "ERROR: no role_arn found in ~/.aws/config for profile '$src_profile'." >&2 | |
exit 1 | |
fi | |
orig_role_name=${orig_role_arn##*/} | |
# determine whether we're switching admin‑style or view‑only | |
if [[ $orig_role_name == *-InfraAnalysis ]]; then | |
mode=viewonly | |
echo "→ detected InfraAnalysis source role → will assume HIPViewOnlyRole on targets" | |
elif [[ $orig_role_name == *-2FA-hip-admin ]]; then | |
mode=admin | |
echo "→ detected 2FA‑hip‑admin source role → will assume admin on targets" | |
else | |
echo "ERROR: source role name '$orig_role_name' does not match expected patterns." >&2 | |
exit 1 | |
fi | |
# --- 6. iterate CSV & assume-role ------------------------------------------- | |
# skip header, read each line | |
while IFS=',' read -r account_id shortname desc url; do | |
# skip empty lines | |
[[ -z $account_id ]] && continue | |
echo | |
echo "→ processing account: $account_id ($shortname)" | |
if [[ $mode == viewonly ]]; then | |
target_role_name="HIPViewOnlyRole" | |
else | |
# admin mode: embed the target shortname into the role | |
target_role_name="AUR-Resource-AWS-${shortname}-2FA-hip-admin" | |
fi | |
role_arn="arn:aws:iam::${account_id}:role/${target_role_name}" | |
echo " assuming → $role_arn" | |
# perform assume‑role | |
assume_out=$(aws sts assume-role \ | |
--role-arn "$role_arn" \ | |
--role-session-name "${src_profile}-${shortname}-$(date +%s)" \ | |
--duration-seconds 3600 \ | |
--profile "$src_profile" \ | |
) | |
# parse returned credentials | |
AK=$(jq -r .Credentials.AccessKeyId <<<"$assume_out") | |
SK=$(jq -r .Credentials.SecretAccessKey <<<"$assume_out") | |
ST=$(jq -r .Credentials.SessionToken <<<"$assume_out") | |
# write them into your credentials file under [<shortname>] | |
aws configure set aws_access_key_id "$AK" --profile "$shortname" | |
aws configure set aws_secret_access_key "$SK" --profile "$shortname" | |
aws configure set aws_session_token "$ST" --profile "$shortname" | |
aws configure set region ap-southeast-2 --profile "$shortname" | |
echo "✔ stored new profile → [$shortname]" | |
done < <(tail -n +2 "$csv_file") | |
echo | |
echo "All done. You can now use e.g. 'aws sts get-caller-identity --profile <shortname>'" |
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 zsh | |
# aws-multi-role.zsh | |
# Usage: ./aws-multi-role.zsh <env> | |
# Example: ./aws-multi-role.zsh preprod | |
set -euo pipefail | |
# --- 1. prerequisites -------------------------------------------------------- | |
if ! command -v jq >/dev/null; then | |
echo "ERROR: this script requires 'jq'. Please install it and retry." >&2 | |
exit 1 | |
fi | |
# --- 2. mappings ------------------------------------------------------------- | |
typeset -A ENV2PROFILE CSVFILE | |
ENV2PROFILE=( | |
dev servicesdev | |
test servicestest | |
np servicesnp | |
preprod servicespreprod | |
prod servicesprod | |
) | |
CSVFILE=( | |
dev dev.csv | |
test test.csv | |
np np.csv | |
preprod preprod.csv | |
prod prod.csv | |
) | |
# --- 3. parse & validate input ---------------------------------------------- | |
if (( $# != 1 )); then | |
echo "Usage: $0 <environment: dev|test|np|preprod|prod>" >&2 | |
exit 1 | |
fi | |
env=$1 | |
src_profile=${ENV2PROFILE[$env]:-} | |
csv_file=${CSVFILE[$env]:-} | |
if [[ -z $src_profile ]]; then | |
echo "ERROR: invalid environment '$env'." >&2 | |
exit 1 | |
fi | |
if [[ ! -f $csv_file ]]; then | |
echo "ERROR: CSV file '$csv_file' not found for environment '$env'." >&2 | |
exit 1 | |
fi | |
echo "→ using source profile: [$src_profile]" | |
echo "→ reading accounts from: $csv_file" | |
# --- 4. test source credentials --------------------------------------------- | |
if ! aws sts get-caller-identity --profile "$src_profile" &>/dev/null; then | |
echo "ERROR: credentials for profile '$src_profile' are invalid or expired." >&2 | |
exit 1 | |
fi | |
echo "✔ source credentials are valid." | |
# --- 5. detect original role type via sts get-caller-identity --------------- | |
echo "→ fetching ARN of current identity from profile '$src_profile'…" | |
caller_json=$(aws sts get-caller-identity --profile "$src_profile" --output json) | |
orig_arn=$(echo "$caller_json" | jq -r '.Arn') | |
# Arn should look like: | |
# arn:aws:sts::123456789012:assumed-role/ROLE_NAME/SESSION_NAME | |
if [[ $orig_arn != arn:aws:sts::*:assumed-role/* ]]; then | |
echo "ERROR: expected an assumed-role ARN but got: $orig_arn" >&2 | |
exit 1 | |
fi | |
# extract ROLE_NAME (middle segment) | |
orig_role_name=${orig_arn#*assumed-role/} # strips up to 'assumed-role/' | |
orig_role_name=${orig_role_name%%/*} # strips from first '/' onward | |
echo "→ detected source role name: $orig_role_name" | |
if [[ $orig_role_name == *-InfraAnalysis ]]; then | |
mode=viewonly | |
echo "→ will assume HIPViewOnlyRole on targets" | |
elif [[ $orig_role_name == *-2FA-hip-admin ]]; then | |
mode=admin | |
echo "→ will assume AUR-Resource‑…‑2FA‑hip-admin on targets" | |
else | |
echo "ERROR: role name '$orig_role_name' does not match expected patterns." >&2 | |
exit 1 | |
fi | |
# --- 6. iterate CSV & assume-role ------------------------------------------- | |
while IFS=',' read -r account_id shortname desc url; do | |
[[ -z $account_id ]] && continue # skip blank lines | |
echo | |
echo "→ processing account: $account_id ($shortname)" | |
if [[ $mode == viewonly ]]; then | |
target_role_name="HIPViewOnlyRole" | |
else | |
target_role_name="AUR-Resource-AWS-${shortname}-2FA-hip-admin" | |
fi | |
role_arn="arn:aws:iam::${account_id}:role/${target_role_name}" | |
echo " assuming → $role_arn" | |
assume_out=$(aws sts assume-role \ | |
--role-arn "$role_arn" \ | |
--role-session-name "${src_profile}-${shortname}-$(date +%s)" \ | |
--duration-seconds 3600 \ | |
--profile "$src_profile" \ | |
) | |
AK=$(jq -r .Credentials.AccessKeyId <<<"$assume_out") | |
SK=$(jq -r .Credentials.SecretAccessKey <<<"$assume_out") | |
ST=$(jq -r .Credentials.SessionToken <<<"$assume_out") | |
aws configure set aws_access_key_id "$AK" --profile "$shortname" | |
aws configure set aws_secret_access_key "$SK" --profile "$shortname" | |
aws configure set aws_session_token "$ST" --profile "$shortname" | |
aws configure set region ap-southeast-2 --profile "$shortname" | |
echo "✔ stored new profile → [$shortname]" | |
done < <(tail -n +2 "$csv_file") | |
echo | |
echo "All done! You can now do, for example:" | |
echo " aws sts get-caller-identity --profile <shortname>" |
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 zsh | |
# aws-multi-role.zsh | |
# Usage: ./aws-multi-role.zsh <env> | |
# Example: ./aws-multi-role.zsh preprod | |
set -euo pipefail | |
# --- 1. prerequisites -------------------------------------------------------- | |
if ! command -v jq >/dev/null; then | |
echo "ERROR: this script requires 'jq'. Please install it and retry." >&2 | |
exit 1 | |
fi | |
# --- 2. mappings ------------------------------------------------------------- | |
typeset -A ENV2PROFILE CSVFILE | |
ENV2PROFILE=( | |
dev servicesdev | |
test servicestest | |
np servicesnp | |
preprod servicespreprod | |
prod servicesprod | |
) | |
CSVFILE=( | |
dev dev.csv | |
test test.csv | |
np np.csv | |
preprod preprod.csv | |
prod prod.csv | |
) | |
# --- 3. parse & validate input ---------------------------------------------- | |
if (( $# != 1 )); then | |
echo "Usage: $0 <environment: dev|test|np|preprod|prod>" >&2 | |
exit 1 | |
fi | |
env=$1 | |
src_profile=${ENV2PROFILE[$env]:-} | |
csv_file=${CSVFILE[$env]:-} | |
if [[ -z $src_profile ]]; then | |
echo "ERROR: invalid environment '$env'." >&2 | |
exit 1 | |
fi | |
if [[ ! -f $csv_file ]]; then | |
echo "ERROR: CSV file '$csv_file' not found for environment '$env'." >&2 | |
exit 1 | |
fi | |
echo "→ using source profile: [$src_profile]" | |
echo "→ reading accounts from: $csv_file" | |
# --- 4. test source credentials --------------------------------------------- | |
if ! aws sts get-caller-identity --profile "$src_profile" &>/dev/null; then | |
echo "ERROR: credentials for profile '$src_profile' are invalid or expired." >&2 | |
exit 1 | |
fi | |
echo "✔ source credentials are valid." | |
# --- 5. detect original role type via sts get-caller-identity --------------- | |
echo "→ fetching ARN of current identity from profile '$src_profile'…" | |
caller_json=$(aws sts get-caller-identity --profile "$src_profile" --output json) | |
orig_arn=$(echo "$caller_json" | jq -r '.Arn') | |
if [[ $orig_arn != arn:aws:sts::*:assumed-role/* ]]; then | |
echo "ERROR: expected an assumed-role ARN but got: $orig_arn" >&2 | |
exit 1 | |
fi | |
orig_role_name=${orig_arn#*assumed-role/} | |
orig_role_name=${orig_role_name%%/*} | |
echo "→ detected source role name: $orig_role_name" | |
if [[ $orig_role_name == *-InfraAnalysis ]]; then | |
mode=viewonly | |
echo "→ will assume HIPViewOnlyRole on targets" | |
elif [[ $orig_role_name == *-2FA-hip-admin ]]; then | |
mode=admin | |
echo "→ will assume AUR-Resource‑…‑2FA‑hip-admin on targets" | |
else | |
echo "ERROR: role name '$orig_role_name' does not match expected patterns." >&2 | |
exit 1 | |
fi | |
# --- 6. iterate CSV & assume-role ------------------------------------------- | |
while IFS=',' read -r account_id shortname desc url; do | |
[[ -z $account_id ]] && continue # skip blank lines | |
echo | |
echo "→ processing account: $account_id ($shortname)" | |
if [[ $mode == viewonly ]]; then | |
target_role_name="HIPViewOnlyRole" | |
else | |
target_role_name="AUR-Resource-AWS-${shortname}-2FA-hip-admin" | |
fi | |
role_arn="arn:aws:iam::${account_id}:role/${target_role_name}" | |
echo " attempting → $role_arn" | |
# --- assume with error handling --- | |
if ! assume_out=$(aws sts assume-role \ | |
--role-arn "$role_arn" \ | |
--role-session-name "${src_profile}-${shortname}-$(date +%s)" \ | |
--duration-seconds 3600 \ | |
--profile "$src_profile" \ | |
2>&1 | |
); then | |
echo "⚠️ Warning: could not assume role on $account_id ($shortname):" | |
echo " ${assume_out##* }" | |
echo " → skipping." | |
continue | |
fi | |
# parse and store | |
AK=$(jq -r .Credentials.AccessKeyId <<<"$assume_out") | |
SK=$(jq -r .Credentials.SecretAccessKey <<<"$assume_out") | |
ST=$(jq -r .Credentials.SessionToken <<<"$assume_out") | |
aws configure set aws_access_key_id "$AK" --profile "$shortname" | |
aws configure set aws_secret_access_key "$SK" --profile "$shortname" | |
aws configure set aws_session_token "$ST" --profile "$shortname" | |
aws configure set region ap-southeast-2 --profile "$shortname" | |
echo "✔ stored new profile → [$shortname]" | |
done < <(tail -n +2 "$csv_file") | |
echo | |
echo "All done! You can now do, for example:" | |
echo " aws sts get-caller-identity --profile <shortname>" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment