LoginSignup
10
7

More than 5 years have passed since last update.

AWS Price List API で雑に月額を出してみる

Last updated at Posted at 2017-06-26

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日で決め打ちです
  • 変えられるべき条件は他にも沢山ある気がします
  • その他未知の不具合があると思います

最後に

もう少しまともなやつをそのうち作ろうと思います。

10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7