share facebook facebook twitter menu hatena pocket slack

2017.07.24 MON

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

WRITTEN BY 山口 与力

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

最後に

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

元記事はこちら

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

山口 与力

最近うどんばかり食べてる蕎麦県民

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。