At-a-glance Amazon EC2 Server Status Bash Script

We use EC2 to host some of our internal application servers, as well as the public-facing production server. We're also using Elastic Bamboo for an on-demand build server, with extremely great results.

One nitpick I've always had with EC2 is how difficult it can be to know how your servers are doing. You can provision some type of external Nagios installation that monitors your servers (and you should be doing this anyway for production environments), but for spin-up and internal servers, it's nice to know what's going on.

I wrote a bash script (tested only on my Mac) that reaches out to AWS, retrieves the EC2 JSON data, and parses/displays it.

Step 1: AWS CLI

Install the AWS CLI using their instructions, or just skip the click and use:

pip install awscli

Once installed, you should then go manually retrieve your Access Key from the IAM Console:

Instructions for snagging the access key/secret

Once you have these two values, run (in your shell of choice):

aws configure

It will ask you for both. You can specify the region in which your servers are mentioned. The default output format can be left as None.

Step 2: The Script

Copypasta this into a shell script, run chmod u+x to ensure it has execute permissions, and give it a run.

#!/bin/bash
echo `date +"%a, %l:%M %p"`  
# Add aws to the PATH (for GeekTool) 
export PATH=$PATH:/usr/local/bin  
JSON_STATUS=`aws ec2 describe-instances --output json`  
INSTANCE_COUNT=`echo $JSON_STATUS | jq '.Reservations | length' 2>&1`  
CURRENT_MS=`date -u +"%s"`  
echo "Running instances: $INSTANCE_COUNT"  
for (( INSTANCE_IDX=0; INSTANCE_IDX<$INSTANCE_COUNT; INSTANCE_IDX++ ))  
do  
        INSTANCE_STATUS=`echo $JSON_STATUS | jq ".Reservations[$INSTANCE_IDX].Instances[0].State.Name"`
        INSTANCE_NAME=`echo $JSON_STATUS | jq ".Reservations[$INSTANCE_IDX].Instances[0].Tags[0].Value"`
        INSTANCE_IP=`echo $JSON_STATUS | jq ".Reservations[$INSTANCE_IDX].Instances[0].NetworkInterfaces[0].Association.PublicIp"`
        INSTANCE_DATE_UP=`echo $JSON_STATUS | jq ".Reservations[$INSTANCE_IDX].Instances[0].LaunchTime"`
        # Remove trailing quote
        temp="${INSTANCE_DATE_UP%\"}"
        # Remove leading quote
        temp="${temp#\"}"
        # This is our final date string
        INSTANCE_DATE_UP=$temp
        INSTANCE_MS_SINCE_EPOCH=`date -u -j -f "%Y-%m-%dT%k:%M:%S" $INSTANCE_DATE_UP "+%s" 2>/dev/null`
        DIFF_IN_MS=`expr $CURRENT_MS - $INSTANCE_MS_SINCE_EPOCH`
        DIFF_UNIT='min'
        DIFF_IN_MIN=`expr $DIFF_IN_MS / 60`
        if [ $DIFF_IN_MIN -gt 120 ]
        then
                DIFF_IN_MIN=`expr $DIFF_IN_MS / 3600`
                DIFF_UNIT='hr'
                if [ $DIFF_IN_MIN -gt 24 ]
                then
                        DIFF_IN_MIN=`expr $DIFF_IN_MS / 86400`
                        DIFF_UNIT='days'
                fi
        fi
        echo "INSTANCE $INSTANCE_IDX [$INSTANCE_NAME]: $INSTANCE_STATUS @ $INSTANCE_IP [ Up $DIFF_IN_MIN $DIFF_UNIT ]" 
done  

Step 3: Output

You should see something like:

Wed, 7:28 PM  
Running instances: 2  
INSTANCE 0 ["Public Test Server"]: "running" @ "54.152.xx.xx" [ Up 42 days ]  
INSTANCE 1 ["Internal Server"]: "running" @ "52.1.xx.xx" [ Up 136 days ]  

IPs redacted - yours will be displayed in full

You can even run this as a GeekTool script, and drop it right onto your desktop:

comments powered by Disqus