1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # Date: Jul 25,2016

  5. '''
  6. ### Purpose ####

  7. Correlating the reservations you currently have active with your running instances is a manual, time-consuming, and error prone process.
  8. This quick little Python script uses boto3 to inspect your reserved instances and running instances to determine if you currently have any reserved instances which are not being used. Additionally, it will give you a list of non-reserved instances which could benefit from additional reserved instance allocations.

  9. ### prequisite ####

  10. 1. requirement(optional): boto3 and termcolor
  11. $ pip install boto3 termcolor (maybe need sudo privilege)

  12. python >= 2.7

  13. 2. aws credentials configuration
  14. See here http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
  15. If you have multiple profiles, you can configure additional, named profiles by using the --profile option.

  16. $ aws configure --profile pcf-China
  17. AWS Access Key ID [None]: xxxxxxxxxxxxxxxxxxxxxxxx
  18. AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxxx
  19. Default region name [None]: cn-north-1
  20. Default output format [None]: text

  21. ##### something else that need your attention !!!!!!

  22. 1. if your Reserved Instance account and Running Instance account are same one, probably you don't need to specify a profile name as below, yet you need to re-write the code under

  23. the initialization of an instance will be :

  24. x = Ec2()

  25. which means a profile name isn't required,it will read from the `default` credentials.

  26. 2. Probably your profile name is different from mine, please modify them on below section

  27. ### aws profile specifications ###

  28. in this script, my reserve profile is reservation, and running instance profile is pcf-China and concourse.

  29. '''
  30. try:
  31.    import sys
  32.    import boto3
  33.    from termcolor import colored
  34. except ImportError:
  35.    print "either boto3 or termcolor isn't installed, please run \"sudo pip install boto3 termcolor\""
  36.    sys.exit(1)

  37. ### aws profile specifications ###

  38. ri_acc_id = ["reservation"]
  39. rn_acc_id = ["pcf-China", "concourse"]

  40. class Ec2 :
  41.     def __init__(self, profile=None) :
  42.         self.profile = profile
  43.         self.session = boto3.session.Session(profile_name = self.profile )
  44.         self.client = self.session.client("ec2")
  45.         self.RI = {}
  46.         self.running_instances = {}

  47.     def Current_ec2_instances(self) :

  48.         for i in self.client.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values': ['running','stopped']}])["Reservations"] :
  49.             tmp = i["Instances"]
  50.             az_type = tmp[0]["Placement"]["AvailabilityZone"],tmp[0]["InstanceType"]
  51.             self.running_instances[az_type]=self.running_instances.get(az_type,0) + 1
  52.         # current ec2 instances, including running/stopped, excluding pending/terminated.
  53.         #print self.running_instances
  54.         return self.running_instances

  55.     def RI_ec2(self) :

  56.         target = self.client.describe_reserved_instances()["ReservedInstances"]
  57.         for i in target :
  58.             # current reserved ec2 instances, excluding pending-payment | active | payment-failed | retired
  59.             if i["State"] == "active" :
  60.                 az_type = i["AvailabilityZone"],i["InstanceType"]
  61.                 self.RI[az_type] = i["InstanceCount"]
  62.         #print self.RI
  63.         return self.RI

  64. #####################################################


  65. def do_calc(ri,running) :

  66.     for key in ri :
  67.         balance = ri[key] - running.get(key,0) # asumme it's zero, if key doesn't appear on RI
  68.         if balance < 0 :
  69.             print "%s\t\t%s" %(key,colored(balance,"red"))
  70.         else :
  71.             print "%s\t\t%d" %(key,balance)
  72.         try :
  73.             del running[key]
  74.         except Exception,e :
  75.             pass
  76.     print "-" * 60
  77.     print colored("Region\t\tInstanceType\t\treserved-instance-need-to-buy","red")
  78.     print "-" * 60
  79.     if running.items() != {}:
  80.         for k,v in running.items() :
  81.             print "%s\t\t%d" % (k,v)

  82. if __name__ == "__main__" :

  83. ### ec2 ###
  84.     print "#" * 33
  85.     print "# EC2 statistic #"
  86.     print "#" * 33
  87.    # ec2 statistics
  88.     ri_instance_sum ={}
  89.     for i in ri_acc_id :
  90.         reserve_ins = Ec2(i)
  91.         y = reserve_ins.RI_ec2()
  92.         # print "### reserved instances details : %s ###" %colored(i,"green")
  93.         # print "-" * 60
  94.         #print colored("Region\t\tInstanceType\t\tAmount","green")
  95.         #print "-" * 60
  96.         for k,v in y.items():
  97.             #print "%s\t\t%d" % (k,v)
  98.             if k not in ri_instance_sum :
  99.                 ri_instance_sum[k] = v
  100.             else :
  101.                 ri_instance_sum[k] = ri_instance_sum[k] + v

  102.     rn_instance_sum = {}
  103.     for i in rn_acc_id :
  104.         x = Ec2(i)
  105.         #print "\n### running instances details : %s ###" %colored(i,"green")
  106.         #print "-" * 60
  107.         #print colored("Region\t\tInstanceType\t\tAmount","green")
  108.         #print "-" * 60
  109.         for k,v in x.Current_ec2_instances().items() :

  110.             #print "%s\t\t%d"%(k,v)

  111.             if k not in rn_instance_sum:
  112.                 rn_instance_sum[k] =v
  113.             else :
  114.                 rn_instance_sum[k] = rn_instance_sum[k] + v

  115.     print "-" * 60
  116.     print colored("Region\t\tInstanceType\t\tBalance","green")
  117.     print "-" * 60
  118.     print colored("\npositive integer means reserved instances remains un-used,while negative integer \nmeans this type of reserved instance is out of capacity, needs to purchase more...","yellow")
  119.     print "-" * 60

  120.     do_calc(ri_instance_sum,rn_instance_sum)

主要是熟悉AWS的Python的boto3。非常的强大,当然也希望官方能给出统计,这样就省得麻烦了。
09-04 15:53