この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
EC2の価格表を生成する必要があったので、その際のコードを公開します。以下をPythonで実装した感じです。
実行環境
- Python 2.7.10
Pythonスクリプト
東京リージョンのオンデマンド価格のみ必要であったため、それ以外の情報は破棄しています。
# coding: utf-8
import json
import re
import sys
import datetime
import urllib2
def __get_price_list(url):
response = urllib2.urlopen(url)
# 最終行のcallbackしているJavaScript行を取得する
callback_line = response.readlines()[-1]
# callback処理の文字列を除去する
js_string = callback_line[len('callback('):-len(');')]
# JSONに変換するためkey部分に""を付ける
p = re.compile(r'([0-9a-zA-Z]*):')
json_string = p.sub((lambda m:'"' + m.group(1) + '":'), js_string)
price_json = json.loads(json_string)
# key: region:operating_system:instance_type, value: price のdictに変換する
prices = {}
for price_per_region in price_json['config']['regions']:
region = price_per_region['region']
if region != 'ap-northeast-1':
continue
for instance_family in price_per_region['instanceTypes']:
for instance_size in instance_family['sizes']:
instance_type = instance_size['size']
for value_column in instance_size['valueColumns']:
operating_system = value_column['name']
price = value_column['prices']['USD']
# priceが N/A の場合はリストに追加しない
if price == 'N/A':
continue
prices[region + ':' + operating_system + ':' + instance_type] = price
return prices
def main(argv):
price_list = {
'created': str(datetime.datetime.now()),
'prices': {}
}
prices = price_list['prices']
# 旧世代
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/linux-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/rhel-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/sles-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/mswin-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/mswinSQL-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/mswinSQLWeb-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/previous-generation/mswinSQLEnterprise-od.min.js'))
# 現行世代
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/rhel-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/sles-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/mswin-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/mswinSQL-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/mswinSQLWeb-od.min.js'))
prices.update(__get_price_list('http://a0.awsstatic.com/pricing/1/ec2/mswinSQLEnterprise-od.min.js'))
print json.dumps(price_list, sort_keys=True, indent=4)
if __name__ == "__main__":
main(sys.argv)
出力結果は以下のようになります。diffが取りやすいようにKeyでソートしてあります。
{
"created": "2017-07-11 20:11:55.347102",
"prices": {
"ap-northeast-1:linux:c1.medium": "0.158",
"ap-northeast-1:linux:c1.xlarge": "0.632",
...
"ap-northeast-1:sles:x1.16xlarge": "9.771",
"ap-northeast-1:sles:x1.32xlarge": "19.441"
}
}
Price List APIを使わないのは?
ドキュメントにも記載がある通り料金ページの方が正となっているためです。
AWS Price List API は料金詳細を参考としてのみ提供します。オファーファイルとサービスの料金ページの間に不一致がある場合、AWS はサービスの料金ページに表示されている料金を請求します。
AWS Price List API の使用 - AWS 請求情報とコスト管理
最後に
CLI上でコマンドをパイプでつなげてワンライナーでやるのはスマートな感じがしますが、ちょっと加工したい場合はPythonのようなスクリプトでやる方が簡単ですよね。参考になれば幸いです。