Skip to content

Instantly share code, notes, and snippets.

/-

Created July 22, 2015 17:59
Show Gist options
  • Save anonymous/fcc5357cdfd1e3572c9c to your computer and use it in GitHub Desktop.
Save anonymous/fcc5357cdfd1e3572c9c to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# Poor mans Consul bootstrap helper. Originally we created a configuration snippit in
# /etc/consul.d with a retry_join host of an ELB endpoint. Murphy's law means that
# on occasion the ELB will have Consul connecting to itself.
#
# The AWS API is queried for a list of ELBs that we're behind, and then we get the
# IPs of all other ELB backends and attempt to join them.
# Print messages
message_print(){
echo "$1" | awk "{ if (NR == 1){ printf \"$(date +%s.%N): %s\n\", \$0 } else { printf \" %s\n\", \$0 } }"
}
# Grab our own instance ID
instance_id=$(ec2metadata --instance-id)
# Get our region
region=$(ec2metadata --availability-zone | sed -e 's/[abcd]$//g')
# Grab our local ipv4 address
instance_local_address=$(ec2metadata --local-ipv4)
# Build aws option string
aws_cli_options="--output json --region $region"
# Grab a list of ELB names that we're behind
elb_names=$(aws $aws_cli_options elb describe-load-balancers 2>/dev/null | jq --raw-output ".LoadBalancerDescriptions[] | {LoadBalancerName, InstanceId: .Instances[].InstanceId} | select(.InstanceId==\"${instance_id}\") | .LoadBalancerName")
if [[ ! "$elb_names" ]]; then
message_print "FAILED: aws elb describe-load-balancers returned no data"
exit 1
fi
# Grab a list of all instances that are behind the same ELBs as us
elb_backend_instances=$(aws $aws_cli_options elb describe-load-balancers --load-balancer-names ${elb_names} 2>/dev/null | jq --raw-output '.LoadBalancerDescriptions[] | .Instances[] | .InstanceId' | sort | uniq)
if [[ ! "$elb_backend_instances" ]]; then
message_print "FAILED: aws elb describe-load-balancers --load-balancer-names ${elb_names} returned no data"
exit 1
fi
# Build list of consul raft peers
consul_peers=$(curl -s "http://${instance_local_address}:8500/v1/status/peers")
if [[ ! "$consul_peers" ]]; then
message_print "FAILED: curl -s http://${instance_local_address}:8500/v1/status/peers returned no data"
exit 1
fi
# Grab the instance address for all those instance IDs and run through them and see if
# there is any we're not connected to.
instance_addresses=""
for instance in ${elb_backend_instances}; do
if [[ ! "$instance" == "$instance_id" ]]; then
instance_address=$(aws $aws_cli_options ec2 describe-instances --filters "Name=instance-id,Values=${instance}" 2>/dev/null | jq --raw-output '.Reservations[] | .Instances[] | .PrivateIpAddress')
instance_addresses="${instance_address//[[:space:]]/} ${instance_addresses}"
fi
done
for instance_address in ${instance_addresses}; do
if [[ "$consul_peers" == "null" ]] || ! (echo "$consul_peers" | jq --raw-output ".[] | select(. == \"${instance_address}:8300\")" | grep -q "^${instance_address}:8300"); then
output=$(consul join "$instance_address")
message_print "$instance_address $output"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment