Parse OnDemand pricing for AWS in Ruby
Sunday, August 04, 2013 Category : AWS, Ruby 1
Well I have been doing a LOT more Ruby programming since my last "Hello World" post. I figured that I should probably start sharing some of the more useful code.
First is this class which gives you a quick and easy way to determine the current OnDemand pricing for an instance type. There is a Gem out there for this already but I wanting something that was small which I understood myself (thats how you learn). The class is not really useful by itself, but I am writing some analysis of Spot pricing (will post when its fully complete) and it really need to be able to dynamically get the current pricing.
What that the code does is pull the current pricing from the Amazon web site, which returns a json file. This file has a deep data structure that is really overboard for most usage. Also, the naming for instance types is very different to the normal 'm1.small' format. Therefore the code does a mapping between the two.
All you need to do is copy and paste the Class into your file and then instantiate the instance and use the price method to get a specific value. For example
puts OnDemandPricing.new.price('ap-southeast-2','t1.micro','linux')
Use at your own risk.
#!/usr/bin/ruby require "rubygems" require "net/http" require "uri" require "json" require "yaml" class OnDemandPricing REGION_MAPPING = { 'us-east' => 'us-east-1', 'us-west' => 'us-west-1', 'us-west-2' => 'us-west-2', 'eu-ireland' => 'eu-west-1', 'apac-tokyo' => 'ap-northeast-1', 'apac-sin' => 'ap-southeast-1', 'apac-syd' => 'ap-southeast-2', 'sa-east-1' => 'sa-east-1'} TYPE_MAPPING = { 'uODI' => 't1', 'stdODI' => 'm1', 'secgenstdODI' => 'm3', 'hiMemODI' => 'm2', 'hiCPUODI' => 'c1', 'clusterComputeI' => 'cc1', 'clusterHiMemODI' => 'cr1', 'clusterGPUI' => 'cg1', 'hiIoODI' => 'hi1', 'hiStoreODI' => 'hs1'} SIZE_MAPPINGS = { 'u' => 'micro', 'sm' => 'small', 'med' => 'medium', 'lg' => 'large', 'xl' => 'xlarge', 'xxl' => '2xlarge', 'xxxxl' => '4xlarge', 'xxxxxxxxl' => '8xlarge'} def autovivifying_hash # A little helper to save initialising the hash as we go, make Ruby more like Perl! # http://en.wikipedia.org/wiki/Autovivification Hash.new do |hash, key| hash[key] = autovivifying_hash end end def initialize uri = URI.parse( "http://aws.amazon.com/ec2/pricing/pricing-on-demand-instances.json") request = Net::HTTP::Get.new(uri.request_uri) http = Net::HTTP.new(uri.host, uri.port) response = http.request(request) data = JSON.parse(response.body) @price_table = autovivifying_hash # Walk the json structure finding the key data and load into an easy to # access hash of hash of hashes # being price_table[REGION][INSTANCE TYPE][OS linux/mswin] returns price data['config']['regions'].each do |reg| reg['instanceTypes'].each do |type| type['sizes'].each do |size| size['valueColumns'].each do |val| @price_table[REGION_MAPPING[reg['region']]] \ [ TYPE_MAPPING[type['type']] + "." + SIZE_MAPPINGS[size['size']] ] \ [val['name']] = val['prices']['USD'] end end end end end def price (region, instance_type, os) return @price_table[region][instance_type][os] end end # Class #An example puts OnDemandPricing.new.price('ap-southeast-2','t1.micro','linux')Enjoy. Any feedback use the comments.