Last active
September 18, 2024 15:13
-
-
Save darksinge/3d35243c3b968b9d1d883680ec0ea2fe to your computer and use it in GitHub Desktop.
A script to look up lambda functions belonging to a Cloudformation stack and open it in a browser window.
This file contains 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 | |
set -e | |
export DEBUG=0 | |
export AWS_REGION="us-east-1" | |
function debug() { | |
if [ $DEBUG -eq 1 ]; then | |
echo "ERROR: $@" >&2 | |
fi | |
} | |
function info() { | |
echo "INFO: $@" >&2 | |
} | |
NO_CACHE=0 | |
CLEAN=0 | |
OPEN_LOG_GROUP=0 | |
help() { | |
cat << EOF | |
Usage: $(basename "$0") [OPTIONS] | |
This script helps you find and open an AWS Lambda function in the AWS Console. | |
Options: | |
-p, --profile PROFILE Specify the AWS profile to use | |
-r, --region REGION Specify the AWS region to use (default: us-east-1) | |
--no-cache Disable caching of AWS resources | |
--clean Clear out cached responses from AWS API calls | |
--stage STAGE Specify the stage (dev/stage/prod/other) | |
--stack-name STACK_NAME Specify the CloudFormation stack name | |
-n, --application-name PREFIX Specify the stack name prefix | |
--debug Enable debug mode | |
--open-log-group Open the CloudWatch log group instead of the Lambda function | |
-h, --help Display this help message and exit | |
The script will prompt you to: | |
1. Choose or enter a stage (dev/stage/prod/other) | |
2. Select a CloudFormation stack | |
3. Choose a Lambda function from the selected stack | |
It will then open the chosen Lambda function in your default web browser. | |
Note: This script requires the following tools to be installed: | |
- AWS CLI | |
- jq | |
- gum (for interactive prompts) | |
EOF | |
} | |
if ! gum -v >/dev/null 2>&1; then | |
echo "The 'gum' command was not found." | |
echo "Visit https://github.com/charmbracelet/gum for installation instructions." | |
exit 1 | |
fi | |
while [[ $# -gt 0 ]]; do | |
case $1 in | |
-p|--profile) | |
export AWS_PROFILE="$2" | |
shift 2 | |
;; | |
--no-cache) | |
export NO_CACHE=1 | |
shift | |
;; | |
--region) | |
export AWS_REGION="$2" | |
shift 2 | |
;; | |
--clean) | |
CLEAN=1 | |
shift | |
;; | |
-s|--stage) | |
STAGE="$2" | |
shift 2 | |
;; | |
--stack-name) | |
STACK_NAME="$2" | |
shift 2 | |
;; | |
-n|--application-name) | |
STACK_PREFIX="$2" | |
shift 2 | |
;; | |
--debug) | |
export DEBUG=1 | |
shift | |
;; | |
--open-log-group) | |
OPEN_LOG_GROUP=1 | |
shift | |
;; | |
-h|--help) | |
help | |
exit 0 | |
;; | |
*) | |
help | |
exit 1 | |
;; | |
esac | |
done | |
CACHE_DIR="$HOME/.cache/find-fn" | |
debug "CACHE_DIR: $CACHE_DIR" | |
if [ ! -d "$CACHE_DIR" ]; then | |
mkdir -p "$CACHE_DIR" | |
fi | |
if [ $CLEAN -eq 1 ]; then | |
rm -rf "$CACHE_DIR" >/dev/null 2>&1 | |
mkdir -p "$CACHE_DIR" | |
info "Cache cleared..." | |
exit 0 | |
fi | |
if [ -z "$STAGE" ]; then | |
STAGE=$(gum choose "dev" "stage" "prod" "other") | |
if [ "$STAGE" == "other" ]; then | |
STAGE=$(gum input --placeholder "stage name?") | |
fi | |
fi | |
function _make_temp() { | |
type="$1" | |
fcache="$CACHE_DIR/$STAGE-$type" | |
if [ $NO_CACHE -eq 1 ]; then | |
echo "$(mktemp)" | |
return 0 | |
fi | |
local tmp="" | |
if [ -f "$fcache" ]; then | |
tmp=$(cat "$fcache") | |
fi | |
if [ ! -f "$tmp" ]; then | |
tmp=$(mktemp) | |
echo "$tmp" > "$fcache" | |
else | |
tmp=$(cat "$fcache") | |
fi | |
echo "$tmp" | |
} | |
function make_temp() { | |
set +e | |
echo $(_make_temp "$1") | |
set -e | |
} | |
stack_list_cache=$(make_temp "stacks_$STACK_PREFIX") | |
debug "stack_list_cache: $stack_list_cache" | |
if [ -f "$stack_list_cache" ]; then | |
STACKS=$(cat "$stack_list_cache") | |
debug "Found cached stacks list in '$stack_list_cache'" | |
fi | |
if [ -z "$STACKS" ]; then | |
debug "Stacks list is empty..." | |
if [ -n "$STACK_PREFIX" ]; then | |
stack_prefix="$STAGE-$STACK_PREFIX-" | |
else | |
stack_prefix="$STAGE-" | |
fi | |
QUERY="StackSummaries[?starts_with(StackName, '$stack_prefix')].StackName" | |
debug "Query: \"$QUERY\"" | |
STACKS=$(gum spin --spinner dot --title 'Fetching stacks' --show-output -- \ | |
aws cloudformation list-stacks \ | |
--query "$QUERY" \ | |
--output json) | |
debug "Fetched stacks: $(echo $STACKS | jq -c '.')" | |
echo "$STACKS" > "$stack_list_cache" | |
fi | |
if [ -z "$STACK_NAME" ]; then | |
STACK_NAME=$(gum filter --limit 1 $(echo "$STACKS" | jq -r '.[]')) | |
fi | |
resource_cache=$(make_temp "$STACK_NAME-resources") | |
if [ -f "$resource_cache" ]; then | |
RESOURCES=$(cat "$resource_cache") | |
fi | |
debug "resource_cache: $resource_cache" | |
if [ -z "$RESOURCES" ]; then | |
RESOURCES=$(gum spin --spinner dot --title 'Fetching resources' --show-output -- \ | |
aws cloudformation list-stack-resources --stack-name "$STACK_NAME" \ | |
--output json) | |
echo "$RESOURCES" > "$resource_cache" | |
fi | |
RESOURCES=$(cat "$resource_cache" | jq '.StackResourceSummaries') | |
LOGICAL_IDS=$( | |
echo "$RESOURCES" \ | |
| jq -r '.[] | select(.ResourceType == "AWS::Lambda::Function") | .LogicalResourceId' \ | |
| gum filter --no-limit --select-if-one | |
) | |
debug "LOGICAL_ID: ${LOGICAL_IDS[*]}" | |
PHYSICAL_IDS=() | |
for LOGICAL_ID in $LOGICAL_IDS; do | |
PHYSICAL_ID=$( | |
echo "$RESOURCES" \ | |
| jq -r ".[] | select(.LogicalResourceId == \"$LOGICAL_ID\") | .PhysicalResourceId" | |
) | |
PHYSICAL_IDS+=("$PHYSICAL_ID") | |
done | |
debug "PHYSICAL_IDS: ${PHYSICAL_IDS[*]}" | |
for ID in "${PHYSICAL_IDS[@]}"; do | |
info "Opening Lambda function: $ID" | |
if [ $OPEN_LOG_GROUP -eq 1 ]; then | |
open "https://$AWS_REGION.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logsV2:log-groups/log-group/%2Faws%2Flambda%2F$ID" | |
else | |
open "https://$AWS_REGION.console.aws.amazon.com/lambda/home?region=$AWS_REGION#/functions/$ID?tab=monitoring" | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment