AWS

現在のインスタンス料金を取得する script: EC2 編

http://qiita.com/bells17/items/5326d11edc6acc4feea2
の EC2 版です

注意点として OS を Linux、 tenancy を Shared に絞っています

ec2.rb
require 'json'
require 'bigdecimal'

results = {}
json_data = open(ARGV[0]) {|io| JSON.load(io) }

# product 情報を取得
json_data['products'].keys.each do |skuNo|
    product = json_data['products'][skuNo]

    if (product['productFamily'] == 'Compute Instance' and
          product['attributes']['locationType'] == 'AWS Region' and
          product['attributes']['location'] == 'Asia Pacific (Tokyo)' and
          product['attributes']['operatingSystem'] == 'Linux' and
          product['attributes']['tenancy'] == 'Shared')

        results[product['sku']] = {
            sku: product['sku'],
            location: product['attributes']['location'],
            instanceType: product['attributes']['instanceType'],
            instanceTypePrefix: product['attributes']['instanceType'].split('.')[0],
            instanceFamily: product['attributes']['instanceFamily'],
            vcpu: product['attributes']['vcpu'],
            memory: product['attributes']['memory'],
            storage: product['attributes']['storage'],
            clockSpeed: product['attributes']['clockSpeed'],
            networkPerformance: product['attributes']['networkPerformance'],
            ecu: product['attributes']['ecu'],
            currentGeneration: product['attributes']['currentGeneration'],
            price_unit: 'USD'
        }

    end
end


# price

## on demand
json_data['terms']['OnDemand'].keys.each do |skuNo|
    if (results[skuNo])
        results[skuNo][:price_per_hour] = Proc.new {
            skuTerm = json_data['terms']['OnDemand'][skuNo][json_data['terms']['OnDemand'][skuNo].keys[0]]
            priceInfo = skuTerm['priceDimensions'][skuTerm['priceDimensions'].keys[0]]
            sprintf('%.3f', BigDecimal(priceInfo['pricePerUnit']['USD']).floor(3).to_f.to_s)
        }.call
        results[skuNo][:price_per_day] = sprintf('%.3f', (BigDecimal(results[skuNo][:price_per_hour]) * BigDecimal("24")).floor(3).to_f.to_s)
        results[skuNo][:price_per_month] = sprintf('%.3f', (BigDecimal(results[skuNo][:price_per_day]) * BigDecimal("30")).floor(3).to_f.to_s)
    end
end

## reserved 
json_data['terms']['Reserved'].keys.each do |skuNo|
    if (results[skuNo])

        plans = json_data['terms']['Reserved'][skuNo].values.select do |plan|
            plan['termAttributes']['PurchaseOption'] == "All Upfront" # "All Upfront" のものだけ取得したい
        end

        results[skuNo][:price_reserved_1year_purchased_all_upfront] = sprintf('%.3f', plans.find { |plan|
            plan['termAttributes']['LeaseContractLength'] == '1yr'
        }['priceDimensions'].values.find {|priceDimension|
            priceDimension['description'] == "Upfront Fee"
        }['pricePerUnit']['USD'])

        results[skuNo][:price_reserved_3year_purchased_all_upfront] = sprintf('%.3f', plans.find { |plan|
            plan['termAttributes']['LeaseContractLength'] == '3yr'
        }['priceDimensions'].values.find {|priceDimension|
            priceDimension['description'] == "Upfront Fee"
        }['pricePerUnit']['USD'])

    end
end


# sort
sorted_result = {}
results.values.each do |row|
    sorted_result[row[:currentGeneration]] ||= {}
    sorted_result[row[:currentGeneration]][row[:instanceFamily]] ||= {}
    sorted_result[row[:currentGeneration]][row[:instanceFamily]][row[:instanceTypePrefix]] ||= []
    sorted_result[row[:currentGeneration]][row[:instanceFamily]][row[:instanceTypePrefix]].push row
end

results = []
['Yes', 'No'].each do |currentGeneration| # 現行世代のものから並べる
    sorted_result[currentGeneration].keys.sort.each do |instanceFamily| # インスタンスファミリー毎に並べる
        sorted_result[currentGeneration][instanceFamily].keys.sort.each do |instanceTypePrefix|
            results.concat sorted_result[currentGeneration][instanceFamily][instanceTypePrefix].sort_by { |row| row[:price_per_hour] }
        end
    end
end

p results.to_json

上記を保存して以下のように実行する

curl https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/index.json > price-AmazonEC2.json
ruby ec2.rb price-AmazonEC2.json | sed -e s/^\"// | sed -e s/\"$// | sed -e 's/\\"/"/g' | jq .

以下のような感じで結果が取れる

[
  {
    "sku": "Q4QTSF7H37JFW9ER",
    "location": "Asia Pacific (Tokyo)",
    "instanceType": "c3.large",
    "instanceTypePrefix": "c3",
    "instanceFamily": "Compute optimized",
    "vcpu": "2",
    "memory": "3.75 GiB",
    "storage": "2 x 16 SSD",
    "clockSpeed": "2.8 GHz",
    "networkPerformance": "Moderate",
    "ecu": "7",
    "currentGeneration": "Yes",
    "price_unit": "USD",
    "price_per_hour": "0.128",
    "price_per_day": "3.072",
    "price_per_month": "92.160",
    "price_reserved_1year_purchased_all_upfront": "753.000",
    "price_reserved_3year_purchased_all_upfront": "1528.000"
  },
  {
    "sku": "HTNXMK8Z5YHMU737",
    "location": "Asia Pacific (Tokyo)",
    "instanceType": "c3.xlarge",
    "instanceTypePrefix": "c3",
    "instanceFamily": "Compute optimized",
    "vcpu": "4",
    "memory": "7.5 GiB",
    "storage": "2 x 40 SSD",
    "clockSpeed": "2.8 GHz",
    "networkPerformance": "Moderate",
    "ecu": "14",
    "currentGeneration": "Yes",
    "price_unit": "USD",
    "price_per_hour": "0.255",
    "price_per_day": "6.120",
    "price_per_month": "183.600",
    "price_reserved_1year_purchased_all_upfront": "1505.000",
    "price_reserved_3year_purchased_all_upfront": "3032.000"
  },
  {
    "sku": "YR67H6NVBRN37HRZ",
    "location": "Asia Pacific (Tokyo)",
    "instanceType": "c3.2xlarge",
    "instanceTypePrefix": "c3",
    "instanceFamily": "Compute optimized",
    "vcpu": "8",
    "memory": "15 GiB",
    "storage": "2 x 80 SSD",
    "clockSpeed": "2.8 GHz",
    "networkPerformance": "High",
    "ecu": "28",
    "currentGeneration": "Yes",
    "price_unit": "USD",
    "price_per_hour": "0.511",
    "price_per_day": "12.264",
    "price_per_month": "367.920",
    "price_reserved_1year_purchased_all_upfront": "3012.000",
    "price_reserved_3year_purchased_all_upfront": "8132.000"
  },
...
]