AWS CLI commands to get Monthly Cost of newly created EC2 Instances

There's an API call behind every activity we perform on our AWS Console. When we launch a new EC2, the RunInstances event is called behind the scenes. AWS Cloudtrail is a service, where we can view which user has performed what activity.

Plan

Cloudtrail cli command will give us RunInstances API call details. (A unique ID - event ID to be more specific) Using this event ID we can get the instance IDs of our newly created EC2 instance. Then it's really simple to get its details using the ec2-describe instances command.

Cloudtrail CLI commands

date=$(date '+%Y-%m-%d') 
ids=()

for i in $(aws cloudtrail lookup-events 
--lookup-attributes AttributeKey=EventName,AttributeValue=RunInstances
--query 'Events[].{eventid:EventId}' --output text --region ap-south-1 
--start-time $date)

do 
  ids[$counter]=$i;
  let counter=counter+1

done

We will store these cloud trail event IDs in an array (Array name -> ids) so that we can iterate over it & get instance IDs. date variable will get today's date.

  • Why did we store it in an array?

The above command will give us many event IDs, we need to store them, & important thing is to filter out the genuine API calls.

  • What do I mean by genuine API calls?

    • This API call is also triggered when autoscaling happens.

    • It's also called when someone uses the dry-run option.

Autoscaling - When there's a sudden increase in incoming traffic, servers are increased to handle the load. When this traffic comes back to normal, the server is automatically terminated. Works only if we have autoscaling enabled

dry-run - Often used to check if a user has required permission or not to run a particular command, it will call the API behind the scenes to check everything, but will not create the instance.

Getting Instance ID

for i in "${ids[@]}"
do
  instance_ID=$(aws cloudtrail lookup-events 
--query "Events[0].CloudTrailEvent" --output text --lookup-attribute AttributeKey=EventId,AttributeValue=$i --region ap-south-1 
| jq -r '.' | jq -r '.responseElements.instancesSet.items[0].instanceId')

  echo "$instance_ID;" >> instance_ids.csv
done

We appended Instance IDs to a CSV file & we have added a semicolon after the instance ID so that when we iterate over our CSV file, we can use a semicolon(;) as a field separator, to get the instance name & its type of each instance ID.

Getting Instance Name and type by its ID

while IFS=',' read -r ids; do
   instance_name=$(aws ec2 describe-tags --region ap-south-1
--filters "Name=resource-id,Values=$ids" "Name=key,Values=Name" 
--output text | cut -f5)

   instance_type=$(aws ec2 describe-instances --instance-ids $ids --region ap-south-1 | jq -r '.' 
| jq -r '.Reservations[0].Instances[0].InstanceType')

done < instance-ids.csv

We iterated over our instance-ids.csv & for each instance-id, we got its name & type.

Monthly Cost

Since we got its instance type above, it's very easy to get its monthly cost.

cost=$(curl -sL 'ec2.shop?filter='"$instance_type"'' -H 'accept: json' 
| jq . | jq '.Prices[0].MonthlyPrice')

Using ec2.shop you can get prices of all instance types. By specifying our instance type, we can get its Monthly cost.

Now you can push these things to Grafana for a centralized view of these details.

Thanks for reading.