import boto.ec2 def get_running_instances(region): ec2 = boto.ec2.connect_to_region(region) instances = [i for r in ec2.get_all_reservations() for i in r.instances] return filter(lambda i: i.state == 'running', instances) def get_reserved_instances(region): ec2 = boto.ec2.connect_to_region(region) reserved_instances = ec2.get_all_reserved_instances() return filter(lambda i: i.state == 'active', reserved_instances) def get_ri_table(running_instances, reserved_instances): table = {} for i in running_instances: key = (i.vpc_id is not None, i.placement, i.instance_type) if key not in table: table[key] = {'running': 0, 'reserved': 0} table[key]['running'] += 1 for ri in reserved_instances: key = ('VPC' in ri.description, ri.availability_zone, ri.instance_type) if key not in table: table[key] = {'running': 0, 'reserved': 0} table[key]['reserved'] += ri.instance_count return table def print_ri_table(table, header): header_template = "{5} {0:18} {6}|{5} {1:15} {6}|{5} {2:10} {6}|{5} {3:10} {6}|{5} {4:10}{6}" row_template = "{5} {0:18} {6}|{5} {1:15} {6}|{5} {2:10d} {6}|{5} {3:10d} {6}|{5} {4:10d}{6}" keys = table.keys() keys.sort() print "\033[1;37;49m {0} \033[00m\n".format(header) print header_template.format("Availability Zone", "Instance Type", "RIs", "Instances", "Diff", "\033[1;37;49m", "\033[00m") print "-" * 78 for key in keys: value = table[key] diff = value['reserved'] - value['running'] color = "\033[0;37;49m" if diff < 0: color = "\033[0;31;49m" elif diff > 0: color = "\033[0;34;49m" print row_template.format(key[1], key[2], value['reserved'], value['running'], diff, color, "\033[00m") def main(): running_instances = get_running_instances('us-east-1') reserved_instances = get_reserved_instances('us-east-1') table = get_ri_table(running_instances, reserved_instances) print_ri_table({x:y for x,y in table.iteritems() if x[0] == False}, 'EC2-Classic') print "\n" print_ri_table({x:y for x,y in table.iteritems() if x[0] == True}, 'EC2-VPC') if __name__ == '__main__': main()