1
0
mirror of https://github.com/HariSekhon/DevOps-Bash-tools.git synced 2025-02-06 09:28:21 +00:00
DevOps-Bash-tools/.envrc-aws
2024-12-17 02:28:27 +07:00

203 lines
6.4 KiB
Bash

#!/usr/bin/env bash
# vim:ts=4:sts=4:sw=4:et
#
# Author: Hari Sekhon
# Date: 2021-07-27 12:42:32 +0100 (Tue, 27 Jul 2021)
#
# https://github.com/HariSekhon/DevOps-Bash-tools
#
# License: see accompanying Hari Sekhon LICENSE file
#
# If you're using my code you're welcome to connect with me on LinkedIn and optionally send me feedback to help steer this or other code I publish
#
# https://www.linkedin.com/in/HariSekhon
#
# ============================================================================ #
# A W S D i r E n v
# ============================================================================ #
# https://direnv.net/man/direnv-stdlib.1.html
# See Also:
#
# .envrc
# .envrc-gcp
# .envrc-kubernetes
# direnv stdlib - loads .envrc from parent dir up to /
#
# useful to accumulate parent and child directory .envrc settings eg. adding Kubernetes namespace, ArgoCD app etc.
#
# bypasses security authorization though - use with care
#source_up
#
# source_up must be loaded before set -u otherwise gets this error:
#
# direnv: loading .envrc
# /bin/bash: line 226: $1: unbound variable
set -euo pipefail
[ -n "${DEBUG:-}" ] && set -x
srcdir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -n "${CI:-}" ]; then
exit 0
fi
# XXX: Edit - crucial to set to the right environment, the rest of the inferred settings below depend on this
if [ -z "${AWS_PROFILE:-}" ]; then
exit 0
fi
aws configure list 2>/dev/null || :
echo
# If not logged in:
#
# - and we know the AWS_PROFILE
# - and AWS_NO_AUTOLOGIN is not set
# - check for SSO key in config section for this profile
# - if found then do an automatic 'aws sso login'
#
if ! aws sts get-caller-identity --output table; then
if [ -n "${AWS_PROFILE:-}" ] &&
[ -z "${AWS_NO_AUTOLOGIN:-}" ]; then
# assumes you're not putting a blank line until the next section block
#if sed -n "/profile.*$AWS_PROFILE/,/^[[:space:]]*$/p" ~/.aws/config | grep -q sso_start_url; then
# goes until the next [profile ...] section instead, should be more reliable
if sed -n "/profile.*$AWS_PROFILE/,/^[[:space:]]*\[.+\]/p" ~/.aws/config | grep -q sso_start_url; then
echo
aws sso login
fi
fi
fi
echo
# 'aws sts get-caller-identity --query Account' succeeds in returning the account id
# from the ~/.aws/config even if 'aws sso login' has expired
AWS_ACCOUNT_ID="$(
aws sts get-caller-identity --query Account --output text ||
aws configure get sso_account_id ||
:
)"
echo "AWS Account ID: $AWS_ACCOUNT_ID"
export AWS_ACCOUNT_ID
echo
# might not have permissions to the Organizations in which case this will error instead of return
AWS_ACCOUNT="$(aws organizations describe-account --account-id "$AWS_ACCOUNT_ID" 2>/dev/null)"
if [ -n "$AWS_ACCOUNT" ]; then
echo "AWS Account: $AWS_ACCOUNT"
export AWS_ACCOUNT
echo
fi
AWS_DEFAULT_REGION="$(aws configure get region || :)" # use region configured in profile by default
AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION:-eu-west-1}" # XXX: Edit default fallback region
export AWS_DEFAULT_REGION
echo "AWS Region: $AWS_DEFAULT_REGION"
echo
export AWS_DEFAULT_OUTPUT=json
# XXX: Edit, or remove if only have 1 cluster in account, will auto-determine below
export EKS_CLUSTER="mycluster"
# safer but slower
#eks_clusters=()
#while IFS='' read -r line; do
# eks_clusters+=("$line")
##done < <(aws eks list-clusters --output=json | jq -r '.clusters[]')
#done < <(aws eks list-clusters --query 'clusters[]' --output text)
#if [ "${#eks_clusters[@]}" -eq 1 ]; then
# export EKS_CLUSTER="${eks_clusters[*]}"
#fi
eks_clusters="$(
aws eks list-clusters --query 'clusters' --output text |
tr '[:space:]' '\n' |
sed '/^[[:space:]]*$/d'
)"
if [ -n "$eks_clusters" ]; then
num_eks_clusters="$(grep -c . <<< "$eks_clusters")"
echo "EKS Clusters ($num_eks_clusters):"
echo
echo "$eks_clusters"
echo
# If EKS_CLUSTER isn't set and there is only one EKS cluster in this account and region, then use it
if [ -z "${EKS_CLUSTER:-}" ]; then
if [ "$num_eks_clusters" = 1 ]; then
EKS_CLUSTER="$eks_clusters"
fi
fi
else
num_eks_clusters=0
fi
if [ -n "${EKS_CLUSTER:-}" ]; then
# kubectl context is easily created by running adjacent aws_kube_creds.sh script first
export EKS_CONTEXT="arn:aws:eks:$AWS_DEFAULT_REGION:$AWS_ACCOUNT_ID:cluster/$EKS_CLUSTER"
if command -v kubectl &>/dev/null; then
if ! kubectl config get-clusters | grep -Fxq "$EKS_CONTEXT"; then
echo "EKS Cluster '$EKS_CLUSTER' not configured, configuring now"
aws eks update-kubeconfig --name "$EKS_CLUSTER"
echo
fi
fi
# XXX: safer to inline .envrc-kubernetes if you're worried about changes to it bypassing 'direnv allow' authorization
# shellcheck disable=SC1090,SC1091
. "$srcdir/.envrc-kubernetes" "$EKS_CONTEXT" ${EKS_NAMESPACE:+"$EKS_NAMESPACE"}
fi
if [ "$num_eks_clusters" = 1 ]; then
if grep -q '^[[:space:]]*export[[:space:]]*EKS_CLUSTER' .envrc &&
! grep -q "^export EKS_CLUSTER=$eks_clusters$" .envrc; then
echo
echo "Updating EKS_CLUSTER in .envrc from:"
echo
grep '^[[:space:]]*export[[:space:]]*EKS_CLUSTER' .envrc
echo
echo "to"
echo
echo "export EKS_CLUSTER=$eks_clusters"
echo
perl -pi -e "s/^\\s*export\s+EKS_CLUSTER=.*/export EKS_CLUSTER=$eks_clusters/" .envrc
echo
fi
fi
# better to load this dynamically from credentials, using functions in .bash.d/aws.sh
#export AWS_ACCESS_KEY_ID=...
#export AWS_SECRET_ACCESS_KEY=...
#export AWS_SESSION_TOKEN=...
#export AWS_CONFIG_FILE=~/.aws/config
#export AWS_SHARED_CREDENTIALS_FILE=~/.aws/credentials
#export AWS_MAX_ATTEMPTS=3
# to quickly export prefixed AWS environment keys if they exist for simple overrides, see examples below
aws_access_key_env(){
env="$1"
for key in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY; do
varname="${env}_${key}"
if [ -n "${!varname:-}" ]; then
export "$key"="${!varname}"
fi
done
}
#aws_access_key_env "DEV"
#aws_access_key_env "STAGING"
#aws_access_key_env "PROD"
#aws_access_key_env "MGMT"
# pull the secret using this command whenever you need it:
#
# aws_secret_get.sh "$JENKINS_ADMIN_PASSWORD_AWS_SECRET" | copy_to_clipboard.sh
#
export JENKINS_ADMIN_PASSWORD_AWS_SECRET="jenkins-admin-password"