#!/usr/bin/env bash
# vim:ts=2:sw=2:tw=79
set -Eeuo pipefail
shopt -s extglob
shopt -s nocasematch
shopt -s extdebug
# Secure environment.
IFS=$' \t\n'
unset -f unalias
# shellcheck disable=SC1001
\unalias -a
unset -f command
if ! PATH="$(command -p getconf PATH 2>/dev/null)" && [[ -z "$PATH" ]]; then
PATH="/usr/bin:/bin"
fi
PATH+=":/usr/local/bin" # Optionally necessary for Homebrew on Darwin.
# shellcheck disable=SC2154
trap 'declare rc=$?;
>&2 echo "Unexpected error (exit-code $rc) executing $BASH_COMMAND at ${BASH_SOURCE[0]} line $LINENO";
exit $rc' ERR
activeAwsEc2 () {
# https://docs.aws.amazon.com/cli/latest/reference/ce/get-cost-and-usage.html
myFilter () {
printf '{"And":[%s{"Dimensions":{"Key":"SERVICE","Values":["Amazon Elastic Compute Cloud - Compute"]}},
{"Dimensions":{"Key":"RECORD_TYPE","Values":["Usage"]}},
{"Not":{"Dimensions":{"Key":"INSTANCE_TYPE","Values":[""]}}}]}' \
"${1:-}"
}
aws ce get-cost-and-usage \
--time-period "Start=$(printf "%(%Y-%m-%d)T" "$(($(date +%s)-(60*60*48)))"),End=$(date +%Y-%m-%d)" \
--granularity MONTHLY \
--metrics "UsageQuantity" \
--group-by "Type=DIMENSION,Key=${1:-REGION}" \
--output json \
--profile CostExplorer \
--filter "$(myFilter "${2:-}")" \
| jq -re '[.ResultsByTime[].Groups[].Keys|add]|unique[]|select(. != "global")'
}
getProfileByAccountId () {
while read -r profile
do
if [[ "$(aws configure get "profile.$profile.sso_account_id")" == "$1" ]]
then
echo "$profile"
break
fi
done < <(aws configure list-profiles | grep -- ReadOnly)
}
main () {
while read -r accountId
do
while read -r region
do
profile="$(getProfileByAccountId "$accountId")"
>&2 printf "account=%s profile=%s region=%s\n" "$accountId" "$profile" "$region"
if ! aws sts get-caller-identity >/dev/null 2>&1
then
aws sso login --profile "$profile"
fi
accountAlias="$(aws iam list-account-aliases --query AccountAliases[0] --output text --profile "$profile")"
accountId="$(aws sts get-caller-identity --query Account --output text --profile="$profile")"
while read -r instance tagName
do
(
printf '["%s","%s","%s","%s","%s"]' "$accountId" "$accountAlias" "$region" "$instance" "$tagName"
aws ssm describe-instance-information \
--output json --profile "$profile" --region "$region" \
--filters "Key=InstanceIds,Values=$instance" \
--query 'InstanceInformationList[].[PlatformType, PlatformName, PlatformVersion][0]'
) | jq -res 'add|@csv'
done < <(aws ec2 describe-instances \
--output text --profile "$profile" --region "$region" \
--query "Reservations[].Instances[].[InstanceId, Tags[?Key=='Name'].Value|[0]]")
done < <(activeAwsEc2 REGION "$(printf '{"Dimensions":{"Key":"LINKED_ACCOUNT","Values":["%s"]}},' "$accountId")")
done < <(activeAwsEc2 LINKED_ACCOUNT)
}
main "$@"