cloudpack あら便利カレンダー 2017 の20日目です。
まえがき
AWS Price List API を使うと AWS 各種サービスの使用料金を巨大な JSON の形式で取得できます。
例えば EC2 のインスタンス使用料金を知りたい場合、 https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/region_index.json
を取得し、そこに含まれる目的のリージョンのオファーファイルを取得します。
$ curl -I https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/20170605233259/ap-northeast-1/index.json HTTP/1.1 200 OK Content-Type: application/octet-stream Content-Length: 10293063 Connection: keep-alive Date: Mon, 19 Jun 2017 04:27:13 GMT Last-Modified: Tue, 06 Jun 2017 00:55:29 GMT ETag: "35bdcd83d7f7863f5f26550206b0e624" Accept-Ranges: bytes Server: AmazonS3 Age: 24112 X-Cache: Hit from cloudfront Via: 1.1 41f313008af830d498dcb13814523bd7.cloudfront.net (CloudFront) X-Amz-Cf-Id: 1oUuTPzPmELzB65fwzB1ds1ezCEpBn8ZWVANIJT-rURfG2p8buOFMg==
上記は東京リージョンの EC2 の例ですが、 Content-Length: 10293063
というどう見ても人間が素で読む量ではないし、テキストエディターに読み込むのも若干ためらわれるサイズです。
公式のドキュメントによると…
JSON ファイルを使用して EC2 のリザーブドインスタンスを確認するには
1. JSON ファイルをからダウンロードします。
2. 適切なプログラムで JSON ファイルを開きます。この例では、Notepad++ を使用します。
3. Ctrl キーを押しながら F キーを押します。
4. [Find what:] に [reserved] と入力します。
5. [Find All in Current Document] を選択します。
とあんまりなので、もう少し楽に価格を調べられる雑スクリプトを作りました。
スクリプト本体
ec2ZatsuPrice.js
const region = process.env["AWS_REGION"] || "us-east-1"; const instanceType = process.env["INSTANCE_TYPE"] || "c4.large"; const tenancy = process.env["TENANCY"] || "Shared"; const operatingSystem = process.env["OPERATING_SYSTEM"] || "Linux"; const offerType = process.env["OFFER_TYPE"] || "OnDemand"; // ↑フィルター条件をenvで指定してね const axios = require("axios"); const api = axios.create({ baseURL: "https://pricing.us-east-1.amazonaws.com" }); Promise.resolve().then(() => { return api.get("/offers/v1.0/aws/AmazonEC2/current/region_index.json") }).then(regionIndexResponse => { const currentVersionUrl = regionIndexResponse.data.regions[region].currentVersionUrl; return api.get(currentVersionUrl); }).then(currentVersionResponse => { const filteredProducts = []; for (productCode in currentVersionResponse.data.products) { const product = currentVersionResponse.data.products[productCode]; if (product.attributes.instanceType !== instanceType) continue; if (product.attributes.tenancy !== tenancy) continue; if (product.attributes.operatingSystem !== operatingSystem) continue; filteredProducts.push(product); } if (filteredProducts.length > 1) { console.log(`絞りきれなかったかも… (${filteredProducts.length} products)`); process.exit(1); }; const offers = currentVersionResponse.data.terms[offerType][filteredProducts[0].sku]; if (Object.keys(offers).length > 1) { console.log(`絞りきれなかったかも… (${Object.keys(offers).length} offers)`); process.exit(1); }; const offer = offers[Object.keys(offers)[0]]; const priceDimension = offer.priceDimensions[Object.keys(offer.priceDimensions)[0]]; const pricePerUnit = parseFloat(priceDimension.pricePerUnit.USD); const monthlyPrice = pricePerUnit * 24 * 30; console.log(JSON.stringify({ region, instanceType, tenancy, operatingSystem, monthlyPrice, description: priceDimension.description, }, undefined, 2)) }).catch(e => console.log(e));
あまり古くない Node.js と axios が必要です。
使い方
叩くだけです。
$ node ec2ZatsuPrice.js { "region": "us-east-1", "instanceType": "c4.large", "tenancy": "Shared", "operatingSystem": "Linux", "monthlyPrice": 72.00000000000001, "description": "$0.1 per On Demand Linux c4.large Instance Hour" }
条件を変えたいときは環境変数で。
$ AWS_REGION=us-west-2 INSTANCE_TYPE=r3.xlarge node ec2ZatsuPrice.js { "region": "us-west-2", "instanceType": "r3.xlarge", "tenancy": "Shared", "operatingSystem": "Linux", "monthlyPrice": 239.76000000000002, "description": "$0.333 per On Demand Linux r3.xlarge Instance Hour" }
オレゴンの r3.xlarge 、オンデマンドの Linux インスタンスは月額だいたい240ドルくらいということがわかります。
雑な部分
- EC2 しか対応してません
- Reserved Instances (1プロダクト複数オファーターム)に対応してません
- 1カ月 == 30日で決め打ちです
- 変えられるべき条件は他にも沢山ある気がします
- その他未知の不具合があると思います
最後に
もう少しまともなやつをそのうち作ろうと思います。