Created
April 28, 2026 18:59
-
-
Save tosin2013/3d53e4ab3f9d090174fb2f8e2dc9ca2f to your computer and use it in GitHub Desktop.
configure-aws-cli.sh
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
| #!/bin/bash | |
| #set -xe | |
| function checkForProgramAndInstall() { | |
| command -v $1 > /dev/null 2>&1 | |
| if [[ $? -eq 0 ]]; then | |
| printf '%-72s %-7s\n' $1 "PASSED!"; | |
| else | |
| sudo yum install -y $1 | |
| fi | |
| } | |
| # Print usage | |
| usage() { | |
| echo -n "${0} [OPTION] | |
| Options: | |
| -i, --install Install awscli latest binaries | |
| -d, --delete Remove awscli | |
| -h, --help Display this help and exit | |
| USAGE: $0 -i aws_access_key_id aws_secret_access_key aws_region | |
| " | |
| } | |
| if [ "$EUID" -ne 0 ] | |
| then | |
| RUN_SUDO="sudo" | |
| fi | |
| # Resolve the aws binary regardless of PATH state, install location, or | |
| # whether the wrapper symlink at /usr/local/bin/aws was (re)created. | |
| # Sets AWS_BIN to an absolute path on success. | |
| resolve_aws_bin() { | |
| if command -v aws >/dev/null 2>&1; then | |
| AWS_BIN="$(command -v aws)" | |
| elif [ -x /usr/local/bin/aws ]; then | |
| AWS_BIN="/usr/local/bin/aws" | |
| elif [ -x /usr/local/aws-cli/v2/current/bin/aws ]; then | |
| AWS_BIN="/usr/local/aws-cli/v2/current/bin/aws" | |
| else | |
| # Last resort: any installed version under /usr/local/aws-cli/v2/<ver>/bin/aws. | |
| # This catches the case where the installer skipped and the 'current' symlink | |
| # was never created (or was stale). -xtype f (instead of -type f) is required | |
| # because bin/aws is a symlink to ../dist/aws in the v2 layout. | |
| local cand | |
| cand="$(${RUN_SUDO} find /usr/local/aws-cli/v2/ -mindepth 3 -maxdepth 3 \ | |
| -path '*/bin/aws' -xtype f -executable 2>/dev/null \ | |
| | sort -V | tail -n 1)" | |
| if [ -n "$cand" ] && [ -x "$cand" ]; then | |
| AWS_BIN="$cand" | |
| else | |
| echo "Error: aws CLI binary not found after install" >&2 | |
| return 1 | |
| fi | |
| fi | |
| export AWS_BIN | |
| return 0 | |
| } | |
| function install_aws_cli(){ | |
| checkForProgramAndInstall curl | |
| checkForProgramAndInstall unzip | |
| # Idempotent download + extract. Skip the curl if we already have the zip, | |
| # and use -o so unzip overwrites in place instead of prompting interactively | |
| # when aws/ exists from a previous run. -q keeps the noise down. | |
| if [ ! -f awscliv2.zip ]; then | |
| curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" | |
| fi | |
| unzip -oq awscliv2.zip | |
| # Heads-up if a system install exists but isn't traversable by the current | |
| # user. We can't fix it without root, but flagging it tells the operator | |
| # there's stale state to clean up. | |
| if [ -d /usr/local/aws-cli/v2 ] && [ ! -r /usr/local/aws-cli/v2 ]; then | |
| echo "NOTE: System AWS CLI exists at /usr/local/aws-cli/v2 but is not" | |
| echo " readable by $(id -un). Continuing with per-user install." | |
| echo " To remove the orphaned install, root can run:" | |
| echo " sudo rm -rf /usr/local/aws-cli /usr/local/bin/aws /usr/local/bin/aws_completer" | |
| echo " To fix perms in place instead:" | |
| echo " sudo chmod -R a+rX /usr/local/aws-cli" | |
| fi | |
| # On boxes where vpcuser can't traverse /usr/local/aws-cli/v2 (perms locked | |
| # to root), do a per-user install under $HOME/.local instead. No sudo, no | |
| # symlink games, and $HOME/.local/bin is already first in PATH for vpcuser. | |
| # --update makes the install command idempotent in either branch. | |
| if [ "$(id -un)" = "vpcuser" ]; then | |
| AWS_INSTALL_DIR="$HOME/.local/aws-cli" | |
| AWS_BIN_DIR="$HOME/.local/bin" | |
| mkdir -p "$AWS_BIN_DIR" "$AWS_INSTALL_DIR" | |
| ./aws/install --update -i "$AWS_INSTALL_DIR" -b "$AWS_BIN_DIR" | |
| # Belt-and-suspenders: prepend to PATH for this shell, and persist for | |
| # future logins if not already in .bashrc. | |
| case ":$PATH:" in | |
| *":$AWS_BIN_DIR:"*) ;; | |
| *) export PATH="$AWS_BIN_DIR:$PATH" ;; | |
| esac | |
| grep -qxF "export PATH=\"$AWS_BIN_DIR:\$PATH\"" "$HOME/.bashrc" 2>/dev/null \ | |
| || echo "export PATH=\"$AWS_BIN_DIR:\$PATH\"" >> "$HOME/.bashrc" | |
| else | |
| # Force a sane umask so the install tree comes out world-readable | |
| # regardless of what the calling shell's umask is. This prevents the | |
| # 0700-on-/usr/local/aws-cli/v2 bug we hit on the vpcuser box: a | |
| # restrictive umask (e.g. 077) at install time makes the entire tree | |
| # untraversable for non-root users. The subshell scopes the umask | |
| # change so we don't perturb the rest of the script. | |
| ( umask 022 && ${RUN_SUDO} ./aws/install --update -i /usr/local/aws-cli -b /usr/local/bin ) | |
| # Post-install fix-up. When --update detects the same version is already | |
| # installed, the installer prints "Skipping install" and does NOT create | |
| # or refresh /usr/local/aws-cli/v2/current or /usr/local/bin/aws. If | |
| # those were missing/stale going in (as on the broken box), they stay | |
| # missing/stale on the way out. Repoint them at the latest version | |
| # directory unconditionally — cheap and idempotent. Also force-open the | |
| # tree perms so non-root users (vpcuser, etc.) can traverse and execute, | |
| # which fixes the original "command not found" failure for non-root | |
| # callers even if they're not the ones running this branch. | |
| latest_dir="$(${RUN_SUDO} find /usr/local/aws-cli/v2/ -mindepth 1 -maxdepth 1 \ | |
| -type d ! -name current 2>/dev/null | sort -V | tail -n 1)" | |
| if [ -n "$latest_dir" ] && [ -d "$latest_dir" ]; then | |
| ${RUN_SUDO} ln -sfn "$latest_dir" /usr/local/aws-cli/v2/current | |
| ${RUN_SUDO} ln -sf /usr/local/aws-cli/v2/current/bin/aws /usr/local/bin/aws | |
| ${RUN_SUDO} ln -sf /usr/local/aws-cli/v2/current/bin/aws_completer /usr/local/bin/aws_completer | |
| ${RUN_SUDO} chmod -R a+rX /usr/local/aws-cli | |
| fi | |
| fi | |
| resolve_aws_bin || exit 1 | |
| "$AWS_BIN" --version || exit 1 | |
| if [ "$EUID" -ne 0 ] | |
| then | |
| rm -rf ${HOME}/awscli-bundle ${HOME}/awscli-bundle.zip | |
| else | |
| rm -rf /root/awscli-bundle /root/awscli-bundle.zip | |
| fi | |
| export AWSKEYID=${1} | |
| export AWSSECRETKEY=${2} | |
| export REGION=${3} | |
| mkdir -p $HOME/.aws | |
| cat >$HOME/.aws/credentials<<EOF | |
| [default] | |
| aws_access_key_id = ${AWSKEYID} | |
| aws_secret_access_key = ${AWSSECRETKEY} | |
| region = ${REGION} | |
| EOF | |
| cat $HOME/.aws/credentials | |
| if [ -z "$SKIP_CHECK_CALLER_IDENTITY" ] | |
| then | |
| "$AWS_BIN" sts get-caller-identity || exit $? | |
| fi | |
| } | |
| function delete_aws_cli(){ | |
| echo "*******************************" | |
| echo " Removing aws cli " | |
| echo "*******************************" | |
| ${RUN_SUDO} rm -rf /usr/local/bin/aws | |
| ${RUN_SUDO} rm -rf /usr/local/aws-cli/v2/ | |
| if [ "$EUID" -ne 0 ] | |
| then | |
| rm -rf $(find $HOME -name awscliv2.zip) | |
| if [ -d $(pwd)/aws ]; | |
| then | |
| rm -rf $(pwd)/aws | |
| fi | |
| else | |
| rm -rf /root/awscli-bundle /root/awscli-bundle.zip | |
| rm -rf /root/awscliv2.zip | |
| rm -rf /root/aws | |
| fi | |
| exit 0 | |
| } | |
| optstring=v | |
| unset options | |
| while (($#)); do | |
| case $1 in | |
| # If option is of type -ab | |
| -[!-]?*) | |
| # Loop over each character starting with the second | |
| for ((i=1; i < ${#1}; i++)); do | |
| c=${1:i:1} | |
| # Add current char to options | |
| options+=("-$c") | |
| # If option takes a required argument, and it's not the last char make | |
| # the rest of the string its argument | |
| if [[ $optstring = *"$c:"* && ${1:i+1} ]]; then | |
| options+=("${1:i+1}") | |
| break | |
| fi | |
| done | |
| ;; | |
| # If option is of type --foo=bar | |
| --?*=*) options+=("${1%%=*}" "${1#*=}") ;; | |
| # add --endopts for -- | |
| --) options+=(--endopts) ;; | |
| # Otherwise, nothing special | |
| *) options+=("$1") ;; | |
| esac | |
| shift | |
| done | |
| set -- "${options[@]}" | |
| unset options | |
| # Read the options and set stuff | |
| while [[ $1 = -?* ]]; do | |
| case $1 in | |
| -h|--help) usage >&2; break ;; | |
| -i|--install) shift; install_aws_cli $1 $2 $3;; | |
| -d|--delete) shift; delete_aws_cli;; | |
| --endopts) shift; break ;; | |
| *) die "invalid option: '$1'." ;; | |
| esac | |
| shift | |
| done | |
| # Store the remaining part as arguments. | |
| args+=("$@") | |
| if [ -z $1 ]; | |
| then | |
| usage | |
| exit 1 | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment