AWS A through Z… Boto Soup… Some clever title P1

I’ve been staying up a bit longer than I usually do and wanted to dedicate some time to Amazon Web Services (AWS), with emphasis on the S. I’ve been cooking up a bit boto soup to check all the AWS managed services. These are simple checks (initially), just one or two checks per service to see if it is in use. Applications for doing this are many, I just would like to get a bit more familiar with the Boto API and the AWS services.

Let’s write a simple class that helps us with managing the credentials

class AwsServiceScanner:
    def __init__(self, key, secret):
        self.key = key
        self.secret = secret

if __name__ == "__main__":
    key, secret = os.environ['AWS_ACCESS_KEY_ID'], os.environ['AWS_SECRET_ACCESS_KEY']
    scanner = AwsServiceScanner(key, secret)

Nothing fancy, just pull the environment variables and add them as instance variables of a an empty class. What we want to do is to go through EVERY service and determine if it is being used, the results of which will be saved to a dictionary. Every service in in every region that is.

    def is_ec2_in_use(self):
        for region in boto.ec2.regions():
            conn = boto.ec2.connect_to_region(region.name,
                                              aws_access_key_id=self.key,
                                              aws_secret_access_key=self.secret)
            print len(conn.get_all_instances()) != 0

Easy enough to determine it EC2 is being used, we simply iterate through the regions, connect to each one and pull the instances. If instances are returned, then we know the service is in use. We can do a bit better, let’s try to print the service (EC2) and the region.

    def is_ec2_in_use(self):
        name = "EC2 ({!s})\t\t"
        for region in boto.ec2.regions():
            conn = boto.ec2.connect_to_region(region.name,
                                              aws_access_key_id=self.key,
                                              aws_secret_access_key=self.secret)
            print {name.format(region.name): len(conn.get_all_instances()) != 0}

Now we can tell if a service in a region is being used, here is an attempt to generalize the pattern.

    def is_service_in_use(self, name, region_name, fn, params={}):
        try:
            service_region_name = name.format(region_name)
            if SERVICES.has_key(service_region_name):
                SERVICES[service_region_name] = SERVICES[service_region_name] or len(fn(**params)) != 0
            else:
                SERVICES[service_region_name] = len(fn(**params)) != 0
        except:
            print "Error calling '"+fn.__name__+"()' for "+name.format(region_name)

    def is_ec2_in_use(self):
        name = "EC2 ({!s})\t\t"
        for region in boto.ec2.regions():
            conn = boto.ec2.connect_to_region(region.name,
                                              aws_access_key_id=self.key,
                                              aws_secret_access_key=self.secret)
            self.is_service_in_use(name, region.name, conn.get_all_instances)
            self.is_service_in_use(name, region.name, conn.get_all_addresses)

To be continued…