Programmatically Retrieving AWS Pricing

Amazon Web Services pricing can make a Wall Street derivatives algorithm look simple. Each service has its own unique pricing scheme with sophisticated multi-variable equations and in some cases price tiering. To make matters worse, the pricing varies by region and is subject to change with little or no advance notice.

For a moderate user of AWS, the published pricing on the web or a third party cost management service will be enough to get by. But sometimes you want programmatic access to Amazon pricing. To help expedite this process, I wrapped the undocumented internal APIs used on the Amazon web site into a small Ruby gem called amazon-pricing. This gem provides users the ability to programmatically retrieve AWS pricing for all EC2 instance types in all regions.

Our example will use both the amazon-pricing and fog gems, which can be retrieved as follows:

$ gem install fog Successfully installed fog-1.1.2 1 gem installed Installing ri documentation for fog-1.1.2... Building YARD (yri) index for fog-1.1.2... Installing RDoc documentation for fog-1.1.2... $ gem install amazon-pricing Successfully installed amazon-pricing-0.0.3 1 gem installed Installing ri documentation for amazon-pricing-0.0.3... Building YARD (yri) index for amazon-pricing-0.0.3... Installing RDoc documentation for amazon-pricing-0.0.3...

To demonstrate the amazon-pricing gem, we have written a simple script that retrieves the on-demand price per month for all of your instances in an AWS account and exports it in CSV format.

#!/usr/bin/env ruby require 'rubygems' require 'fog' require 'amazon-pricing' ACCESS_KEY = "YOUR_AWS_KEY" SECRET_KEY = "YOUR_AWS_SECRET_KEY" compute = Fog::Compute.new( :provider => :aws, :aws_secret_access_key => ACCESS_SECRET, :aws_access_key_id => SECRET_KEY ) # Retrieve pricing price_list = AwsPricing::PriceList.new puts "Region,Availability Zone,Instance Id,Instance IP,Instance Type,On-Demand Price Per Month" compute.servers.each do |server| instance_type = price_list.get_instance_type(server.availability_zone, :on_demand, server.flavor_id) if instance_type.platform == 'windows' price_per_month = instance_type.windows_price_per_hour*24*30.4 else price_per_month = instance_type.linux_price_per_hour*24*30.4 end puts "#{instance_type.region.name},#{server.availability_zone},#{server.id},#{server.public_ip_address},#{server.flavor_id},$#{price_per_month}" end

Here is a sample run of the script:

us-east,us-east-1d,i-10301a75,0.0.0.0,c1.medium,$124.032 us-east,us-east-1d,i-fb313e9f,0.0.0.0,c1.medium,$124.032 us-east,us-east-1d,i-22e222f1,0.0.0.0,m1.xlarge,$496.128

I am currently using this gem in an internal cloud asset management tool at Sonian. It is integrated to retrieve and historically retain daily pricing, allowing us to not only project the real-time cost of our infrastructure, but also to analyze potential cost savings (e.g. comparing on-demand to reserved instances).

It's a pretty simple gem at this point, with much left to add. Let me know if you have features you’d like to see in a future version.