Azure Retail Prices APIで最安VMサイズを調べる方法
はじめに
Azure Retail Prices APIを使って、一番安いVMは何かを調べてみました!
Pricing CalculatorやAzure Portalはインスタンスシリーズ毎の最安は確認できますが、全てのインスタンスシリーズを横断して最安を比較する用途には向いていません。
この用途はAzure Retail Prices APIを使うと一発で最安サイズを取得することができます。
ちなみに、現時点で東日本リージョンの最安VMサイズはStandard_B1lsです。
2026/04/14時点では、1USD=160.14JPYとして料金計算されるため、
最小構成のOSディスクを構成すると、月額は約1,040円になります。(昔に比べ円安で高くなりました…)
- B1lsのVM本体:1.089円 × 730時間 = 約795円/月
- HDD OSディスク:S4 = 約245円/月
合計:約1,040/月
この記事では、Azure Retail Prices APIを使って東日本リージョンの従量課金VMから最安構成を確認してみます。
あわせて、現時点で最安のStandard_B1lsがどのようなVMなのかも、VMサイズ名の規則から解説します。
Azure Retail Prices APIでAzureの料金を確認する
Azure Retail Prices APIとは
Azure Retail Prices APIは、Azureの各サービスの利用料金を取得することができます。このAPIは認証不要で使用できます。
このAPIで取得できるのは、Retail Price(定価みたいなもの)です。
契約割引後の価格や個別見積もり価格を知りたい場合は、別のAPI(Price Sheet API)を使う必要があります。こちらは認証が必要なAPIです。
用途の違いは次のようになります。
| API | 取得できるもの | 認証 | 主な用途 |
|---|---|---|---|
| Azure Retail Prices API | 公開小売価格 | 不要 | SKUやリージョンごとの公開価格比較 |
| Price Sheet API | 契約ベースの価格表 | 必要 | 契約価格の取得 |
Azure Retail Prices APIでAzure VMの料金を調べてみる
今回は、東日本リージョンの従量課金VMの中から最安構成を確認してみます。
やることはシンプルで、APIエンドポイント https://prices.azure.com/api/retail/prices に対してHTTP GETリクエストを送信するだけで取得できます。
GETパラメーターを使い、次の条件で絞り込みます。
- VMの料金だけ
serviceName eq 'Virtual Machines' - 東日本リージョンの料金だけ
armRegionName eq 'japaneast' - 通常の従量課金だけ(予約価格は除外する)
priceType eq 'Consumption'
デフォルトの通貨はドルなので日本円の料金を取るように指定します。
- 通貨は日本円
currencyCode='JPY'
このようなcurlコマンドを実行することで結果を取得することができます。
curl -s -G 'https://prices.azure.com/api/retail/prices' \
--data-urlencode "\$filter=serviceName eq 'Virtual Machines' and armRegionName eq 'japaneast' and priceType eq 'Consumption'" \
--data-urlencode "currencyCode='JPY'"
Azure Retail Prices APIは、1回のAPI呼び出しで取得できるのが最大1,000件で、レスポンスはページングされます。続きはNextPageLinkをたどって取得する必要があります。
以下のスクリプトで全てのページの結果を取得した後、料金の安い順でソートします。
スクリプトはAzure Cloud Shellにコピペで実行できます。
#!/usr/bin/env bash
set -euo pipefail
# Azure Retail Prices APIのエンドポイント
BASE_URL="https://prices.azure.com/api/retail/prices"
# 取得対象:
# - serviceName eq 'Virtual Machines' : 仮想マシン料金だけに絞る
# - armRegionName eq 'japaneast' : 東日本リージョンに絞る
# - priceType eq 'Consumption' : 通常の従量課金に絞る
FILTER="serviceName eq 'Virtual Machines' and armRegionName eq 'japaneast' and priceType eq 'Consumption'"
# currencyCode='JPY' を付けて、日本円の参考価格を取得する
# $filter の値を安全にURLエンコードして初回リクエストURLを作る
FIRST_URL="${BASE_URL}?currencyCode='JPY'&\$filter=$(python3 - <<'PY'
import urllib.parse
filter_str = "serviceName eq 'Virtual Machines' and armRegionName eq 'japaneast' and priceType eq 'Consumption'"
print(urllib.parse.quote(filter_str, safe=""))
PY
)"
# APIの各ページから取得したItemsを1行1JSONで一時ファイルに蓄積する
TMP_FILE="$(mktemp)"
trap 'rm -f "$TMP_FILE"' EXIT
# 次ページがなくなるまでNextPageLinkをたどる
url="$FIRST_URL"
while [ -n "$url" ]; do
response="$(curl -s "$url")"
# そのページのItemsを追記
echo "$response" | jq -c '.Items[]' >> "$TMP_FILE"
# 次ページURLを取得。なければ空文字になる
url="$(echo "$response" | jq -r '.NextPageLink // empty')"
done
# 収集した全件に対して以下を実施:
# 1. 通常利用時の最安構成を見たいので、SpotやLow Priorityは除外
# 2. retailPrice昇順で並べ替え
# 3. 先頭20件だけ取得
# 4. 必要な列だけ抜き出してTSV化
# 5. columnで表っぽく整形
jq -s -r '
map(
select(
(.skuName // "" | test("Spot|Low Priority"; "i") | not)
and
(.meterName // "" | test("Spot|Low Priority"; "i") | not)
)
)
| sort_by(.retailPrice)
| .[0:20] # 先頭20件だけ取得
| (
["currencyCode", "armSkuName", "skuName", "meterName", "retailPrice", "unitOfMeasure", "productName"],
(.[] | [
.currencyCode,
.armSkuName,
.skuName,
.meterName,
(.retailPrice | tostring),
.unitOfMeasure,
.productName
])
)
| @tsv
' "$TMP_FILE" | column -t -s $'\t'
このスクリプトのポイントは2つです。
1つ目は、NextPageLinkをたどって全件取得していることです。
Retail Prices APIは1回で全件返してくれないため、1ページ目だけでは最安を正しく判定できません。
2つ目は、SpotやLow Priorityを除外していることです。
単純に安い順で見るとSpot系が混ざりやすいため、通常の従量課金VMの最安構成を見たいときは除外しておくのがわかりやすいです。
スクリプトの実行結果から安いものを5件だけ貼り付けると、例えば次のようになります。
currencyCode armSkuName skuName meterName retailPrice unitOfMeasure productName
JPY Standard_B1ls B1ls B1ls 1.0890 1 Hour Virtual Machines BS Series
JPY Standard_B2pts_v2 B2pts v2 B2pts v2 1.7296 1 Hour Virtual Machines Bpsv2 Series
JPY Standard_B1ls B1ls B1ls 1.7296 1 Hour Virtual Machines BS Series Windows
JPY Standard_B2ats_v2 B2ats v2 B2ats v2 1.9698 1 Hour Virtual Machines Basv2 Series
JPY Standard_B2ts_v2 B2ts v2 B2ts v2 2.1780 1 Hour Virtual Machines Bsv2 Series
この結果を見ると、東日本リージョンの通常従量課金VMではB1lsが1.089円/時間で最安であることがわかります。
Pricing CalculatorでもB1lsは1.089円/時間であることが確認できます。

現時点の最安サイズであるB1lsは、どんなVMなのか
Azure VMのサイズ名には規則があり、以下規則で命名されています。
[ファミリ][サブファミリ][vCPU数][-追加機能][世代]
この規則に沿って、Standard_B1lsを分解すると次のように読めます。
-
B
Bシリーズです。普段は低負荷だが、ときどきバーストしたいワークロード向けのVMです。CPUクレジットを貯めて、必要時にバーストできるのが特徴です。 -
1
vCPU数です。Azureの命名規則では、数字部分はvCPU数を表します。 -
l
low memoryです。vCPUに対してメモリ比率が低いことを表します。 -
s
Premium SSD compatibleです。Premium SSDに対応していることを表します。
つまり、B1lsは「バースト可能なBシリーズで、1vCPU、低メモリ、Premium SSD対応の小型VM」という読み方になります。
このあたりを見ると、B1lsは「とにかく最小コストで1台立てたい」ときの候補ではありますが、性能面ではかなり小さいことがわかります。
ファミリ等で絞り込みも可能
最安構成を探すだけなら、前述のように東日本リージョンの従量課金VMを全件取得して、価格順に並べれば十分です。
ただ、「B系だけ見たい」「あるシリーズだけ見たい」といったこともあります。
Azure Retail Prices APIでは、公式ドキュメント上、$filterで使えるフィールドとして次のものが案内されています。
B系だけ見たい場合は、以下の様に$filterでstartswith(skuName, 'B')も加えればOKです。
curl -s -G 'https://prices.azure.com/api/retail/prices' \
--data-urlencode "\$filter=serviceName eq 'Virtual Machines' and armRegionName eq 'japaneast' and priceType eq 'Consumption' and startswith(armSkuName, 'Standard_B')" \
--data-urlencode "currencyCode='JPY'" \
| jq -r '.Items[] | [.armSkuName,.skuName,.retailPrice,.unitOfMeasure,.currencyCode]|@tsv' \
| column -t -s $'\t'
Price Sheet APIとは
名前が似ているので少しだけ整理しておきます。
今回のように、Azureの公開価格から最安構成を機械的に探したいのであれば、Azure Retail Prices APIが一番わかりやすいです。
一方で、自社契約の単価や実際の利用額を見たい場合は、別のAPIを使い分ける必要があります。
最後に
Azureで最安のVMサイズを、Azure Retail Prices APIでサクッと探してみました。
Azure Retail Prices APIはAzure各サービスの公開価格を認証不要で取得できるAPIで、今回は分かりやすい例としてVMを例に挙げましたが、VMだけでなく他のAzureサービスにも使えます。
Pricing CalculatorやAzure Portalを目視で追いかける以外にも、Azure Retail Prices APIを使うと、リージョン・課金種別・除外条件でフィルタして一覧取得。スクリプトで加工ができるので、使い分けると便利ですね。
Discussion