Skip to content

Instantly share code, notes, and snippets.

@fbrnc
Last active March 13, 2017 19:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fbrnc/180850cbbd20ea1f55c44a2141790cd1 to your computer and use it in GitHub Desktop.
Save fbrnc/180850cbbd20ea1f55c44a2141790cd1 to your computer and use it in GitHub Desktop.
"Good enough" leader election script for AWS AutoScalingGroups
#!/usr/bin/env bash
function echoerr { echo "$@" 1>&2; }
function error_exit { echoerr "$1"; exit 1; }
if [ -z "${REGION}" ] ; then error_exit "No REGION set"; fi
command -v jq >/dev/null 2>&1 || error_exit "'jq' not found"
command -v aws >/dev/null 2>&1 || error_exit "'aws' not found"
command -v tee >/dev/null 2>&1 || error_exit "'tee' not found"
command -v ec2metadata >/dev/null 2>&1 || error_exit "'ec2metadata' not found"
function getAsgName() {
MAX_CACHE_AGE=86400
INSTANCE_ID=$1
CACHE_FILENAME="/tmp/asglookup_${INSTANCE_ID}"
if [ -f ${CACHE_FILENAME} ] ; then
LAST_MODIFIED=$(stat -c %Y ${CACHE_FILENAME})
NOW=$(date +%s)
AGE=$((NOW-LAST_MODIFIED))
if [ "${AGE}" -lt "${MAX_CACHE_AGE}" ] ; then
cat "${CACHE_FILENAME}"
return;
fi
fi
ASG_NAME=$(aws --output text --region "${REGION}" ec2 describe-tags --filters "Name=resource-id,Values=${INSTANCE_ID}" "Name=key,Values=aws:autoscaling:groupName" --query "Tags[0].Value")
echo "${ASG_NAME}" | tee ${CACHE_FILENAME}
}
function getOldestInstance() {
MAX_CACHE_AGE=60
ASG_NAME=$1
CACHE_FILENAME="/tmp/oldestinstancelookup_${ASG_NAME}"
if [ -f ${CACHE_FILENAME} ] ; then
LAST_MODIFIED=$(stat -c %Y ${CACHE_FILENAME})
NOW=$(date +%s)
AGE=$((NOW-LAST_MODIFIED))
if [ "${AGE}" -lt "${MAX_CACHE_AGE}" ] ; then
cat "${CACHE_FILENAME}"
return;
fi
fi
OLDEST_INSTANCE_ID=$(aws --region "${REGION}" ec2 describe-instances --filters "Name=tag:aws:autoscaling:groupName,Values=${ASG_NAME}" "Name=instance-state-name,Values=running" | jq -r '[.Reservations[].Instances[]] | sort_by(.LaunchTime)[0] | .InstanceId')
echo "${OLDEST_INSTANCE_ID}" | tee ${CACHE_FILENAME}
}
THIS_INSTANCE_ID=$(ec2metadata --instance-id)
ASG_NAME=$(getAsgName ${THIS_INSTANCE_ID})
OLDEST_INSTANCE_ID=$(getOldestInstance ${ASG_NAME})
if [ "${THIS_INSTANCE_ID}" != "${OLDEST_INSTANCE_ID}" ] ; then
exit 1;
fi
@fbrnc
Copy link
Author

fbrnc commented Jun 17, 2016

Usage:

is_leader.sh && echo "Yes, I am the leader"
is_leader.sh || echo "No, I'm not the leader"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment