aws pricingコマンドでAmazon RDSのオンデマンド料金を取得してみた

aws pricingコマンドでAmazon RDSのオンデマンド料金を取得してみた

AWS CLIでAWS Price List Query APIを用いてAmazon RDSのオンデマンド料金を一括取得する方法を試しました。DBエンジンとリージョンくらいを指定すればあとは一括で取れるだろうと思っていたわたしの思いは打ち砕かれました。
2026.09.29

コンバンハ、千葉(幸)です。

最近はAmazon RDSリザーブドインスタンスに興味があります。先日は、AWS CLIを用いて特定リージョン/特定DBエンジンの組み合わせにおいて「実質的な1時間あたりの料金」を一括で取得する方法を試しました。(そこから派生して「期間や支払い方法について購入可能な組み合わせを確認する」というのが本筋のブログになりましたが……)

https://dev.classmethod.jp/articles/rds-ri-purchase-options-availability-guide/

せっかくなら「オンデマンド料金と比較した実質的な費用節減割合」も一括で取得したくなります。

そうなるとすでに取得方法がわかっている「リザーブドインスタンスの実質的な1時間あたりの料金」のほかに、「1時間あたりのオンデマンド料金」も取得する必要があります。

これはAWS Price List Query APIを用いて取得できるのですが、調べるとなかなか複雑でした。今回はAWS Price List Query APIに対応したAWS CLIコマンドであるaws pricingコマンドの使い方と、各種DBエンジンでオンデマンド料金を取得する際のヒントについてご紹介します。

(それだけでモリモリになってしまったので、取得したオンデマンド料金とリザーブドインスタンスの実質時間単価を比較して費用節減割合を出す、というのはまた次の機会にします。)

先にまとめ

  • aws pricing get-attribute-valuesでAmazon RDSのオンデマンド料金を取得できる
    • リザーブドインスタンスの料金も取得できる(本ブログでは取得しない)
  • aws pricing get-attribute-values実行時に考慮すべき属性がいくつかある。DBエンジンによってその属性が異なる

動作確認環境

今回は下記の環境で動作確認を行っています。

  • macOS
  • Zshバージョン:zsh 5.9 (arm64-apple-darwin25.0)
  • AWS CLIバージョン:aws-cli/2.36.19 Python/3.14.6 Darwin/25.5.0 exe/arm64
  • Jqバージョン:jq-1.6

本ブログで使用するコマンド

本ブログではAWS Price List Query APIに対応したaws pricingの3つのサブコマンドを使用します。

また、いずれのコマンドも共通して下記のオプションを指定します。

  • --service-code AmazonRDS:対象のサービスを指定する
  • --region us-east-1:Pricing APIのエンドポイントを指定する
  • --output json:後続のjqで処理するためJSON形式で出力する

--regionはAPIのエンドポイントを指すものであり、us-east-1固定です。料金を調べたいリージョンを指定する場合はregionCode属性として指定します。

Amazon RDSで指定できるフィルタ属性と値を調べる

オンデマンド料金を取得するにあたって、最終的にはaws pricing get-productsの--filtersに各種属性を指定して絞り込みを行います。まずはそもそもどんな属性が使えてどんな値を指定できるのかを確認します。

フィルタに指定できる属性名の一覧はdescribe-servicesで取得します。サービスコードにAmazon RDSを指定して一覧を確認します。

aws pricing describe-services \
  --service-code AmazonRDS \
  --region us-east-1 \
  --output json \
| jq -r '.Services[0].AttributeNames[]' | sort -f

2026/09時点の実行結果は下記のとおりです。

実行結果
acu
clockSpeed
currentGeneration
databaseEdition
databaseEngine
dedicatedEbsThroughput
deploymentModel
deploymentOption
engineCode
engineMajorVersion
engineMediaType
enhancedNetworkingSupported
extendedSupportPricingYear
group
groupDescription
instanceFamily
instanceType
instanceTypeFamily
LeaseContractLength
licenseModel
limitlesspreview
location
locationType
maxVolumeSize
memory
minVolumeSize
networkPerformance
normalizationSizeFactor
OfferingClass
operation
physicalProcessor
processorArchitecture
processorFeatures
productFamily
PurchaseOption
regionCode
Restriction
servicecode
servicename
storage
storageMedia
termType
unbundledLicensing
usagetype
vcpu
volumeName
volumeType
windowslicensemultiplier
jqで加工していないバージョン
% aws pricing describe-services \
  --service-code AmazonRDS \
  --region us-east-1 \
  --output json
{
    "Services": [
        {
            "ServiceCode": "AmazonRDS",
            "AttributeNames": [
                "termType",
                "productFamily",
                "servicecode",
                "location",
                "locationType",
                "instanceType",
                "currentGeneration",
                "instanceFamily",
                "vcpu",
                "physicalProcessor",
                "memory",
                "storage",
                "networkPerformance",
                "processorArchitecture",
                "engineCode",
                "databaseEngine",
                "licenseModel",
                "deploymentOption",
                "usagetype",
                "operation",
                "instanceTypeFamily",
                "normalizationSizeFactor",
                "regionCode",
                "servicename",
                "unbundledLicensing",
                "LeaseContractLength",
                "PurchaseOption",
                "OfferingClass",
                "databaseEdition",
                "windowslicensemultiplier",
                "group",
                "groupDescription",
                "deploymentModel",
                "clockSpeed",
                "processorFeatures",
                "enhancedNetworkingSupported",
                "engineMediaType",
                "storageMedia",
                "volumeType",
                "minVolumeSize",
                "maxVolumeSize",
                "dedicatedEbsThroughput",
                "volumeName",
                "engineMajorVersion",
                "extendedSupportPricingYear",
                "acu",
                "Restriction",
                "limitlesspreview"
            ]
        }
    ],
    "FormatVersion": "aws_v1"
}

そして、特定の属性に指定できる値の候補はget-attribute-valuesで取得します。下記はdatabaseEngine属性を指定する例です。

aws pricing get-attribute-values \
  --service-code AmazonRDS \
  --attribute-name databaseEngine \
  --region us-east-1 \
  --output json \
| jq -r '.AttributeValues[].Value'

実行結果は下記のとおり。

実行結果
Any
Aurora MySQL
Aurora PostgreSQL
Db2
MariaDB
MySQL (on-premise for Outpost)
MySQL
Oracle (on-premises for Outposts)
Oracle
PostgreSQL (on-premise for Outpost)
PostgreSQL
SQL Server (on-premise for Outpost)
SQL Server
jqで加工していないバージョン
% aws pricing get-attribute-values \
  --service-code AmazonRDS \
  --attribute-name databaseEngine \
  --region us-east-1 \
  --output json
{
    "AttributeValues": [
        {
            "Value": "Any"
        },
        {
            "Value": "Aurora MySQL"
        },
        {
            "Value": "Aurora PostgreSQL"
        },
        {
            "Value": "Db2"
        },
        {
            "Value": "MariaDB"
        },
        {
            "Value": "MySQL (on-premise for Outpost)"
        },
        {
            "Value": "MySQL"
        },
        {
            "Value": "Oracle (on-premises for Outposts)"
        },
        {
            "Value": "Oracle"
        },
        {
            "Value": "PostgreSQL (on-premise for Outpost)"
        },
        {
            "Value": "PostgreSQL"
        },
        {
            "Value": "SQL Server (on-premise for Outpost)"
        },
        {
            "Value": "SQL Server"
        }
    ]
}

DBエンジン属性の値の一覧がわかったので、これとリージョンでフィルタリングすればお目当てのオンデマンド料金の一覧が取れるのでは、と当初期待したのですが、そんな単純な話ではありませんでした。

他の属性についても理解しておく必要があります。2つのコマンドを組み合わせて、全属性の主要な値を一覧にしてみます。

{
  echo "| 属性 | 件数 | 値の候補 |"
  echo "| --- | --- | --- |"
  for attr in $(aws pricing describe-services \
    --service-code AmazonRDS \
    --region us-east-1 \
    --output json \
  | jq -r '.Services[0].AttributeNames[]' | sort -f); do
    aws pricing get-attribute-values \
      --service-code AmazonRDS \
      --attribute-name "$attr" \
      --region us-east-1 \
      --output json \
    | jq -r --arg attr "$attr" '
        [.AttributeValues[].Value] as $v
        | ($v | length) as $n
        | if $n > 15
          then "| `\($attr)` | \($n) | \($v[0:4] | join(" / ")) …など |"
          else "| `\($attr)` | \($n) | \($v | join(" / ")) |"
          end
      '
  done
}

実行イメージは下記の通りです。1行ずつ出力されます。

| 属性 | 件数 | 値の候補 |
| --- | --- | --- |
| `acu` | 1 | 1 |
| `clockSpeed` | 5 | 2.3 GHz / 2.4 GHz / 2.5 GHz / Up to 3.1 GHz / Up to 3.3 GHz |
| `currentGeneration` | 2 | No / Yes |
| `databaseEdition` | 14 | Advanced / Any / Community / Developer / Enterprise Developer / Enterprise-BYOM / Enterprise / Express / Standard Developer / Standard One / Standard Two / Standard-BYOM / Standard / Web |
| `databaseEngine` | 13 | Any / Aurora MySQL / Aurora PostgreSQL / Db2 / MariaDB / MySQL (on-premise for Outpost) / MySQL / Oracle (on-premises for Outposts) / Oracle / PostgreSQL (on-premise for Outpost) / PostgreSQL / SQL Server (on-premise for Outpost) / SQL Server |
| `dedicatedEbsThroughput` | 27 | 1000 Mbps / 10000 Mbps / 12000 Mbps / 1250 Mbps …など |
| `deploymentModel` | 1 | Custom |
| `deploymentOption` | 5 | Multi-AZ (SQL Server Mirror) / Multi-AZ (readable standbys) / Multi-AZ / Single-AZ (Oracle RAC) / Single-AZ |
| `engineCode` | 43 | 0 / 10 / 11 / 12 …など |
| `engineMajorVersion` | 8 | 10 / 11 / 12 / 13 / 14 / 15 / 5.7 / 8.0 |
| `engineMediaType` | 2 | AWS-provided / Customer-provided |
| `enhancedNetworkingSupported` | 1 | Yes |
| `extendedSupportPricingYear` | 4 | Year 1, Year 2 (PP) / Year 1, Year 2 / Year 3 (PP) / Year 3 |
……後略

属性によっては値の数が20,000を超えるので、15を超える場合は出力を省略する方式にしました。

2026/9時点の実行結果に、筆者の理解を備考として付けたものが下記です。

属性 件数 値の候補 備考
acu 1 1 Aurora Capacity Unit。Aurora Serverlessの容量単位
clockSpeed 6 2.3 GHz / 2.4 GHz / 2.5 GHz / Up to 3.0 GHz / Up to 3.1 GHz / Up to 3.3 GHz CPUのクロック周波数
currentGeneration 2 No / Yes 現行世代のインスタンスかどうか。db.m1系などはNo
databaseEdition 14 Advanced / Any / Community / Developer / Enterprise Developer / Enterprise-BYOM / Enterprise / Express / Standard Developer / Standard One / Standard Two / Standard-BYOM / Standard / Web DBエンジンのエディション。Oracle/SQL Server/Db2で価格を一意に絞るのに必須。-BYOM付きはRDS Custom用
databaseEngine 13 Any / Aurora MySQL / Aurora PostgreSQL / Db2 / MariaDB / MySQL (on-premise for Outpost) / MySQL / Oracle (on-premises for Outposts) / Oracle / PostgreSQL (on-premise for Outpost) / PostgreSQL / SQL Server (on-premise for Outpost) / SQL Server DBエンジン種別。(on-premise for Outpost)付きはAWS Outposts用
dedicatedEbsThroughput 27 1000 Mbps / 10000 Mbps / 12000 Mbps / 1250 Mbps …など EBS専用帯域幅。db.m5/db.r5bまでの世代にしか存在しない
deploymentModel 1 Custom RDS Customのレコードにのみ存在
deploymentOption 5 Multi-AZ (SQL Server Mirror) / Multi-AZ (readable standbys) / Multi-AZ / Single-AZ (Oracle RAC) / Single-AZ AZ配置構成。 (SQL Server Mirror)、(Oracle RAC)がつくものはストレージ関連の料金のみ。
engineCode 43 0 / 10 / 11 / 12 …など 「エンジン×エディション×ライセンス形態」を識別する内部コード。後述
engineMajorVersion 8 10 / 11 / 12 / 13 / 14 / 15 / 5.7 / 8.0 エンジンのメジャーバージョン。RDS Extended Support料金のレコードで使われる
engineMediaType 2 AWS-provided / Customer-provided エンジンメディアの提供元。RDS Custom(BYOM)はCustomer-provided
enhancedNetworkingSupported 1 Yes 拡張ネットワーキング対応かどうか
extendedSupportPricingYear 4 Year 1, Year 2 (PP) / Year 1, Year 2 / Year 3 (PP) / Year 3 RDS Extended Supportの年次
group 11 API Request / Aurora Backtrack / Aurora Global Database / Aurora I/O Operation / Provisioned GB / RDS CDC Data Transfer / RDS I/O Operation / RDS Snapshot Export / RDS Zero-ETL Data Transfer / RDS-PIOPS / RDS-Throughput インスタンス時間以外の課金項目のグループ
groupDescription 12 Aurora Backtrack Change Records / Aurora Global Database Replicated IO / Data API requests / Input/Output Operation / Performance Insights API requests / RDS Provisioned GP3 IOPS / RDS Provisioned IO2 IOPS / RDS Provisioned IOPS / RDS Provisioned Throughput / RDS Snapshot Size / RDS Zero-ETL Initial Load and Re-sync Export for Commercial Engines / RDS zero-ETL change data capture records consumed from source RDS engine groupの説明文
instanceFamily 6 Compute optimized / General purpose / Memory optimized / Micro instances / T3 / T4G インスタンスファミリーの用途分類。T3/T4Gは分類名ではなく表記揺れしている
instanceType 417 db.c6gd.12xlarge / db.c6gd.16xlarge / db.c6gd.2xlarge / db.c6gd.4xlarge …など DBインスタンスクラス
instanceTypeFamily 49 C6gd / M1 / M2 / M3 …など DBインスタンスクラスタイプ
LeaseContractLength 2 1yr / 3yr RIの契約期間。termType=Reservedのレコードで使われる
licenseModel 6 Bring your own license / Bring your own media / License included / Marketplace / NA / No license required ライセンス形態。Oracle/SQL Server/Db2で価格を一意に絞るのに必須。Bring your own mediaはRDS Custom、MarketplaceはDb2のmpl
limitlesspreview 1 Yes Aurora Limitless Databaseのプレビュー関連?
location 38 AWS GovCloud (US-East) / AWS GovCloud (US-West) / Africa (Cape Town) / Any …など リージョンの表示名
locationType 2 AWS Outposts / AWS Region 通常リージョンかOutpostsか
maxVolumeSize 4 128 TB / 16 TB / 3 TB / 64 TB ストレージの最大サイズ
memory 43 0.613 GiB / 1 GiB / 1.7 GiB / 1024 GiB …など メモリ容量
minVolumeSize 3 10 GB / 100 GB / 5 GB ストレージの最小サイズ
networkPerformance 66 10 Gbps / 10 Gigabit / 10,000 Mbps / 100 Gbps …など ネットワーク性能
normalizationSizeFactor 38 0.5 / 1.3 / 10.4 / 1152 …など RIのサイズ柔軟性の計算に使う正規化係数。SQL Server全エディションとOracle SE2(li)はNA
OfferingClass 1 standard RIのオファリングクラス。EC2にはconvertibleもあるがRDSはstandardのみ
operation 53 CreateDBInstance:0002 / CreateDBInstance:0003 / CreateDBInstance:0004 / CreateDBInstance:0005 …など 課金オペレーションコード。末尾4桁がengineCodeと一致する
physicalProcessor 21 5th Generation AMD EPYC / AWS Graviton2 / AWS Graviton3 / AWS Graviton4 …など 物理プロセッサ種別
processorArchitecture 3 32-bit or 64-bit / 64-bit / x86 プロセッサアーキテクチャ
processorFeatures 4 Intel AVX, Intel AVX2, Intel AVX512, Intel Turbo / Intel AVX, Intel AVX2, Intel Turbo / Intel AVX; Intel AVX2; Intel Turbo / Intel AVX; Intel Turbo プロセッサの拡張命令セット。区切りが,と;で混在している
productFamily 13 Aurora Global Database / CPU Credits / Database Instance / Database Storage / Limitless / Performance Insights / Provisioned IOPS / Provisioned Throughput / RDSProxy / ServerlessV2 / Serverless / Storage Snapshot / System Operation 課金対象の種別。インスタンス時間料金だけ取るならDatabase Instanceを指定
PurchaseOption 3 All Upfront / No Upfront / Partial Upfront RIの支払い方式
regionCode 37 af-south-1 / ap-east-1 / ap-east-2 / ap-northeast-1 …など リージョンコード
Restriction 1 Limited SKU Usage Aurora Data APIのリクエスト課金にのみ登場
servicecode 1 AmazonRDS サービスコード。--service-codeで指定済みなので固定値
servicename 1 Amazon Relational Database Service サービス名
storage 47 1 x 118 NVMe SSD / 1 x 120 SSD / 1 x 150 NVMe SSD / 1 x 160 SSD …など ストレージ構成
storageMedia 3 AmazonS3 / Magnetic / SSD ストレージメディア種別
termType 2 OnDemand / Reserved 料金体系の種別
unbundledLicensing 2 FALSE / TRUE ライセンスがアンバンドルかどうか
usagetype 25806 AFS1-ASv2-ExtendedSupport:Yr1-Yr2:AuroraPostgreSQL13 / AFS1-Aurora:BackupUsage …など 請求明細に出る使用タイプ
vcpu 16 0 / 128 / 12 / 16 …など vCPU数
volumeName 4 gp2 / gp3 / io1 / io2 EBSボリューム名。ストレージ料金のレコードで使われる
volumeType 9 General Purpose (SSD) / General Purpose-Aurora / General Purpose-GP3 / General Purpose / IO Optimized-Aurora / Magnetic / Provisioned IOPS (SSD) / Provisioned IOPS-IO2 / Provisioned IOPS ボリュームタイプの表示名
windowslicensemultiplier 2 1 / 2 Windowsライセンスの乗数

サービスをAmazon RDSに絞っても、これだけの属性と値が存在します。オンデマンド料金に関連しない属性/値もありますが、単にリージョンとDBエンジンだけ気にしていればいいわけではないことが分かりました。

そして以前にAmazon RDSリザーブドインスタンスの情報を取得した際はaws rds describe-reserved-db-instances-offeringsを使ったのですが、aws pricingでもリザーブドインスタンスのオファリング情報が取得できることに気がつきました。(ひとまず今回は引き続きオンデマンド料金のみを取得します。)

engineCodeの値の一覧を深掘りする

属性enginecodeの値が気になったので一覧を確認してみます。最後の行で横並びで表示しています。

aws pricing get-attribute-values \
  --service-code AmazonRDS \
  --attribute-name engineCode \
  --region us-east-1 \
  --output json \
| jq -r '.AttributeValues[].Value' | sort -n | paste -sd' ' -
0 2 3 4 5 6 8 9 10 11 12 14 15 16 18 19 20 21 27 28 29 34 35 50 51 52 53 210 220 230 231 232 240 241 401 402 403 405 406 407 410 411 420

いろんなコードがありますね。

コードごとのDBエンジン、DBエディション、ライセンスモデル、メディアタイプを確認してみます。

aws pricing get-attribute-values \
  --service-code AmazonRDS \
  --attribute-name engineCode \
  --region us-east-1 \
  --output json \
| jq -r '.AttributeValues[].Value' | sort -n | while IFS= read -r c; do
  aws pricing get-products \
    --service-code AmazonRDS \
    --region us-east-1 \
    --output json \
    --filters "Type=TERM_MATCH,Field=engineCode,Value=$c" \
              "Type=TERM_MATCH,Field=productFamily,Value=Database Instance" \
  | jq -r --arg c "$c" '
      [.PriceList[] | fromjson | .product.attributes] as $r
      | def u(f): ($r | map(f // "-") | unique | join(" / ")) | if . == "" then "-" else . end;
        [$c, ($r | length | tostring),
         u(.databaseEngine), u(.databaseEdition), u(.licenseModel),
         u(.engineMediaType), u(.deploymentModel)]
      | @tsv'
done | { printf 'code\t件数\tengine\tedition\tlicense\tmedia\tdeployModel\n'; cat; } | column -t -s$'\t'

(リージョン等でフィルタせず数万件のデータを対象にしているので、実行完了まで10分強かかりました。)

実行結果を基にまとめてみるとこんな感じに。

code databaseEngine databaseEdition licenseModel engineMediaType 備考
0 Any ー ー ー ストレージ料金等で使われる
2 MySQL ー No license required ー
3 Oracle Standard One ー ー ストレージ料金のみ。提供終了エディション
4 Oracle Standard Bring your own license ー 提供終了エディション。ap-south-1に1件だけ残存
5 Oracle Enterprise Bring your own license ー/Customer-provided db.r5b系だけCustomer-providedが付いている
6 Oracle Standard One ー ー ストレージ料金のみ。提供終了エディション
8 SQL Server Standard ー ー ストレージ/PIOPS料金のみ
9 SQL Server Enterprise ー ー ストレージ/PIOPS料金のみ
10 SQL Server Express License included ー
11 SQL Server Web License included ー
12 SQL Server Standard License included ー
14 PostgreSQL ー No license required ー
15 SQL Server Enterprise License included ー
16 Aurora MySQL ー No license required ー
18 MariaDB ー No license required ー
19 Oracle Standard Two Bring your own license ー
20 Oracle Standard Two License included ー
21 Aurora PostgreSQL ー No license required ー
27 Db2 Community Bring your own license ー
28 Db2 Standard Bring your own license ー
29 Db2 Advanced Bring your own license ー
34 Db2 Standard Marketplace ー
35 Db2 Advanced Marketplace ー
50 SQL Server Standard Developer Bring your own media ー
51 SQL Server Enterprise Developer Bring your own media ー
52 SQL Server Standard Bring your own media Customer-provided
53 SQL Server Enterprise Bring your own media Customer-provided
210 MySQL (on-premise for Outpost) ー No license required ー Outposts
220 PostgreSQL (on-premise for Outpost) ー No license required ー Outposts
230 SQL Server (on-premise for Outpost) Enterprise License included ー Outposts
231 SQL Server (on-premise for Outpost) Standard License included ー Outposts
232 SQL Server (on-premise for Outpost) Web License included ー Outposts
240 Oracle (on-premises for Outposts) Enterprise Bring your own license ー Outposts
241 Oracle (on-premises for Outposts) Standard Two Bring your own license ー Outposts
401 SQL Server Web NA AWS-provided RDS Custom
402 SQL Server Standard NA AWS-provided RDS Custom
403 SQL Server Enterprise NA AWS-provided RDS Custom
405 SQL Server Standard NA Customer-provided RDS Custom
406 SQL Server Enterprise NA Customer-provided RDS Custom
407 SQL Server Developer NA Customer-provided RDS Custom
410 Oracle Enterprise Bring your own license Customer-provided RDS Custom
411 Oracle Standard Two Bring your own license Customer-provided RDS Custom

対応するCodeがひとつしかないDBエンジン(MySQL、PostgreSQL、Aurora MySQL、MariaDB、Aurora PostgreSQL)とは握手したくなります。逆にバリエーションが多いSQL Server、Oracle、Db2とは少し距離を置きたくなります。

Amazon RDSのオンデマンド料金を取得する

ここまで確認した属性の一覧を踏まえて、get-productsでオンデマンド料金を取得していきます。

なお、今回は下記の条件で情報を取得したいとします。

  • 特定リージョンでの特定DBエンジンのオンデマンド料金一覧を取得したい
  • 取得する情報は下記の列からなるとする
    • DBインスタンスクラス
    • MultiAZか否か
    • オンデマンド料金

東京リージョンのMySQLのオンデマンド料金を取得するコマンド例は下記です。

REGION=ap-northeast-1
DBENGINE=MySQL
TS=$(date +%Y%m%d_%H%M%S)

OD_CSV="rds_ondemand_${DBENGINE}_${REGION}_${TS}.csv"

aws pricing get-products \
  --service-code AmazonRDS \
  --region us-east-1 \
  --output json \
  --filters "Type=TERM_MATCH,Field=regionCode,Value=$REGION" \
            "Type=TERM_MATCH,Field=databaseEngine,Value=$DBENGINE" \
            "Type=TERM_MATCH,Field=productFamily,Value=Database Instance" \
| jq -r '
  .PriceList[] | fromjson
  | .product.attributes as $a
  | select($a.deploymentOption=="Single-AZ" or $a.deploymentOption=="Multi-AZ")
  | (.terms.OnDemand // {})[]?.priceDimensions[]?
  | select(.unit=="Hrs")
  | [$a.instanceType, $a.deploymentOption, .pricePerUnit.USD]
  | @csv
' | sort -t, -k1,1 -k2,2 > /tmp/ondemand_body.csv

{ echo '"DBInstanceClass","MultiAZ","OnDemand"'; cat /tmp/ondemand_body.csv; } > "$OD_CSV"

echo "$OD_CSV"

これを実行すると下記のようにcsvファイル名が出力されます。

実行イメージ
rds_ondemand_MySQL_ap-northeast-1_20260929_014420.csv

csvファイルの中身は下記のようにDBインスタンスクラス、MultiAZ、オンデマンド料金が一覧になっています。

% head -n 15  rds_ondemand_MySQL_ap-northeast-1_20260929_014306.csv
"DBInstanceClass","MultiAZ","OnDemand"
"db.m1.large","Multi-AZ","0.5800000000"
"db.m1.large","Single-AZ","0.2900000000"
"db.m1.medium","Multi-AZ","0.2900000000"
"db.m1.medium","Single-AZ","0.1450000000"
"db.m1.small","Multi-AZ","0.1500000000"
"db.m1.small","Single-AZ","0.0750000000"
"db.m1.xlarge","Multi-AZ","1.1700000000"
"db.m1.xlarge","Single-AZ","0.5850000000"
"db.m2.2xlarge","Multi-AZ","1.4800000000"
"db.m2.2xlarge","Single-AZ","0.7400000000"
"db.m2.4xlarge","Multi-AZ","2.9500000000"
"db.m2.4xlarge","Single-AZ","1.4750000000"
"db.m2.xlarge","Multi-AZ","0.7300000000"
"db.m2.xlarge","Single-AZ","0.3650000000"

あとは他のエンジンも冒頭の変数を変えてあげれば同じようにオンデマンド料金一覧が取得できます、めでたしめでたし。

……というわけにもいきませんでした。

DBエンジンごとに気にすべきこと

こと今回やりたいことに関して言えば、DBエンジンごとに気にすべき属性があります。下記表で●が付いている属性は指定もしくはフィルタリングが必要です。

DBエンジン engine edition license storage depModel depOption
MySQL ● ●
PostgreSQL ● ●
MariaDB ●
Aurora MySQL ● ●
Aurora PostgreSQL ● ●
Oracle ● ● ● ●
SQL Server ● ● ● ●
Db2 ● ● ●

表の列名はそれぞれ下記を表します。

列名 属性 説明
engine databaseEngine すべてのエンジンで指定が必要
edition databaseEdition エディションが存在するエンジンでは指定が必要
license licenseModel ライセンスモデル(BYOLなど)が存在するエンジンでは指定が必要
storage storage Auroraの場合、Aurora IO Optimization Modeか否かの指定が必要
depModel deploymentModel Customかどうかの指定が必要
depOption deploymentOption Single-AZ/Multi-AZだけに絞る場合はフィルタリングが必要

取得する情報の列を増やせば絞り込む必要はないのですが、冒頭のブログで取得したRDSリザーブドインスタンスの料金情報とフォーマットを合わせたいので、うまいことコントロールします。

例えばstorageに関するところで言うと、AuroraではAurora IO Optimization Modeというモードがあり、通常のモードと比べてオンデマンド料金が高くなります。

4列にしたイメージ
"DBInstanceClass","MultiAZ","OnDemand","Storage"
"db.r5.12xlarge","Single-AZ","10.9200000000","Aurora IO Optimization Mode"
"db.r5.12xlarge","Single-AZ","8.4000000000","EBS Only"

フィルタリングをしない/かつstorageの値を列に含めないといずれのモードのオンデマンド料金が取得されたかが判別できません。そのため、取得する列を増やさない(3列のまま)のであればフィルタリングが必要というわけです。

deploymentOptionに関しては、MySQLとPostgreSQLの場合、Single-AZ/Multi-AZの他にMulti-AZ (readable standbys)という値も取り得ます。これはマルチAZ DBクラスターを表します。これがノイズになる場合はフィルタリングが必要です。

サーバーサイドのフィルタリング、クライアントサイドのフィルタリング

今回のコマンドでは、サーバーサイドのフィルタリングとして--filtersオプション、クライアントサイドのフィルタリングとしてjqのselectが使用できます。

なるべくサーバーサイドでフィルタリングできたほうがローカルで扱うデータ量が減らせるというメリットがあります。--filtersでは下記のタイプを使用できます。

Type 動作
TERM_MATCH 指定した属性が、指定した値に一致するものだけを返す
EQUALS 指定した値に完全一致する値を持つものを返す
CONTAINS 指定した値を部分文字列として含む値を持つものを返す
ANY_OF 指定した複数の値のうち、いずれかに一致する値を持つものを返す
NONE_OF 指定した複数の値のいずれにも一致しない値を持つものを返す

なるべくDBエンジンに依らない汎用性を持たせたフィルタリングの例としてはこのようになるでしょうか。(もちろん、取りたい値によっては条件は異なります。)

REGION=ap-northeast-1
DBENGINE=MySQL

aws pricing get-products \
  --service-code AmazonRDS \
  --region us-east-1 \
  --output json \
  --filters "$(jq -cn --arg region "$REGION" --arg engine "$DBENGINE" '[
      {Type:"TERM_MATCH", Field:"regionCode",       Value:$region},
      {Type:"TERM_MATCH", Field:"databaseEngine",   Value:$engine},
      {Type:"TERM_MATCH", Field:"productFamily",    Value:"Database Instance"},
      {Type:"ANY_OF",     Field:"deploymentOption", Value:"Single-AZ,Multi-AZ"},
      {Type:"NONE_OF",    Field:"storage",          Value:"Aurora IO Optimization Mode"},
      {Type:"NONE_OF",    Field:"deploymentModel",  Value:"Custom"}
    ]')" \
| jq -r '
  .PriceList[] | fromjson
  ……

--filtersをJSON構文で書くのが少し大仰だ、という時にはショートハンド構文にして、jq側のフィルタリングに任せる方法もあります。見通しがいい方を選ぶといいでしょう。(なお、Single-AZ,Multi-AZのように値にカンマを含む場合はショートハンド構文に対応していません。)

……
  --filters "Type=TERM_MATCH,Field=regionCode,Value=$REGION" \
            "Type=TERM_MATCH,Field=databaseEngine,Value=$DBENGINE" \
            "Type=TERM_MATCH,Field=productFamily,Value=Database Instance" \
| jq -r '
  .PriceList[] | fromjson
  | .product.attributes as $a
  | select($a.deploymentOption=="Single-AZ" or $a.deploymentOption=="Multi-AZ")
  | select($a.storage != "Aurora IO Optimization Mode")
  | select(($a.deploymentModel // "") != "Custom")
……

エディションやライセンスを考え出すとengineCodeを使うほうが楽

「なるべくDBエンジンに依らない汎用性を持たせたフィルタリングの例」などと言って上記にいくつか記載しましたが、Oracle、SQL Server、Db2を対象にすることを考えると、さらにdatabaseEditionやlicenseModelについてもフィルタリングが必要です。

細かい条件分岐を書きたくない、でも環境変数を変えるだけでどのDBエンジンにも対応したコマンドにしたい、ということで、フィルタリング条件にengineCodeを用いることにします。

とはいえengineCodeの種類は先ほど深掘りした通り多岐に渡るので、今回はAmazon RDSリザーブドインスタンスのオファリングで確認できるタイプに絞ってみます。

以前のブログで取得したエンジンタイプ一覧(東京リージョン)
% aws rds describe-reserved-db-instances-offerings \
  --region ap-northeast-1 \
  --output json \
| jq -r '[.ReservedDBInstancesOfferings[].ProductDescription] | unique[]'
aurora-mysql
aurora-postgresql
custom-sqlserver-ee(byol)
custom-sqlserver-ee(li)
custom-sqlserver-se(byol)
custom-sqlserver-se(li)
custom-sqlserver-web(li)
db2-ae(byol)
db2-ae(mpl)
db2-se(byol)
db2-se(mpl)
mariadb
mysql
oracle-ee(byol)
oracle-se2 (byol)
oracle-se2(li)
postgresql
sqlserver-ee(li)
sqlserver-ex(li)
sqlserver-se(li)
sqlserver-web(li)

上記のエンジン名(正確にはProductDescription)と対応するengineCodeをあらかじめマッピングしておき、エンジン名を指定してフィルタリングする方式にします。

REGION=ap-northeast-1
ENGINE="oracle-ee(byol)"
TS=$(date +%Y%m%d_%H%M%S)

engine_code() {
  case "$(echo "$1" | tr -d ' ')" in
    "mysql")                     echo 2 ;;
    "postgresql")                echo 14 ;;
    "mariadb")                   echo 18 ;;
    "aurora-mysql")              echo 16 ;;
    "aurora-postgresql")         echo 21 ;;
    "oracle-ee(byol)")           echo 5 ;;
    "oracle-se2(byol)")          echo 19 ;;
    "oracle-se2(li)")            echo 20 ;;
    "sqlserver-ee(li)")          echo 15 ;;
    "sqlserver-se(li)")          echo 12 ;;
    "sqlserver-web(li)")         echo 11 ;;
    "sqlserver-ex(li)")          echo 10 ;;
    "db2-ae(byol)")              echo 29 ;;
    "db2-ae(mpl)")               echo 35 ;;
    "db2-se(byol)")              echo 28 ;;
    "db2-se(mpl)")               echo 34 ;;
    "custom-sqlserver-ee(byol)") echo 406 ;;
    "custom-sqlserver-ee(li)")   echo 403 ;;
    "custom-sqlserver-se(byol)") echo 405 ;;
    "custom-sqlserver-se(li)")   echo 402 ;;
    "custom-sqlserver-web(li)")  echo 401 ;;
    *) echo "" ;;
  esac
}

ENGINE_CODE=$(engine_code "$ENGINE")
ENGINE_SLUG=$(echo "$ENGINE" | sed -E 's/[[:space:]]+//g; s/[()]/_/g; s/_+$//')

OD_CSV="rds_ondemand_${ENGINE_SLUG}_${REGION}_${TS}.csv"

aws pricing get-products \
  --service-code AmazonRDS \
  --region us-east-1 \
  --output json \
  --filters "Type=TERM_MATCH,Field=regionCode,Value=$REGION" \
            "Type=TERM_MATCH,Field=engineCode,Value=$ENGINE_CODE" \
            "Type=TERM_MATCH,Field=productFamily,Value=Database Instance" \
| jq -r '
  .PriceList[] | fromjson
  | .product.attributes as $a
  | select($a.deploymentOption=="Single-AZ" or $a.deploymentOption=="Multi-AZ")
  | select($a.storage != "Aurora IO Optimization Mode")
  | (.terms.OnDemand // {})[]?.priceDimensions[]?
  | select(.unit=="Hrs")
  | [$a.instanceType, $a.deploymentOption, .pricePerUnit.USD]
  | @csv
' | sort -t, -k1,1 -k2,2 > /tmp/ondemand_body.csv

{ echo '"DBInstanceClass","MultiAZ","OnDemand"'; cat /tmp/ondemand_body.csv; } > "$OD_CSV"

echo "$OD_CSV"

実行した際のイメージは以下。CSVファイル名が表示されます。

rds_ondemand_oracle-ee_byol_ap-northeast-1_20260929_145201.csv

内訳はこのような形に。列を3つに維持し、エディションやライセンスごとにファイルを出し分けする形でのオンデマンド料金の取得が実現できました。

% head -n 15 rds_ondemand_oracle-ee_byol_ap-northeast-1_20260929_145201.csv
"DBInstanceClass","MultiAZ","OnDemand"
"db.m3.2xlarge","Multi-AZ","1.9300000000"
"db.m3.2xlarge","Single-AZ","0.9650000000"
"db.m3.large","Multi-AZ","0.4800000000"
"db.m3.large","Single-AZ","0.2400000000"
"db.m3.medium","Multi-AZ","0.2400000000"
"db.m3.medium","Single-AZ","0.1200000000"
"db.m3.xlarge","Multi-AZ","0.9700000000"
"db.m3.xlarge","Single-AZ","0.4850000000"
"db.m4.10xlarge","Multi-AZ","10.1740000000"
"db.m4.10xlarge","Single-AZ","5.0870000000"
"db.m4.16xlarge","Multi-AZ","16.2816000000"
"db.m4.16xlarge","Single-AZ","8.1408000000"
"db.m4.2xlarge","Multi-AZ","2.0340000000"
"db.m4.2xlarge","Single-AZ","1.0170000000"

まとめ(再掲)

  • aws pricing get-attribute-valuesでAmazon RDSのオンデマンド料金を取得できる
    • リザーブドインスタンスの料金も取得できる(本ブログでは取得しない)
  • aws pricing get-attribute-values実行時に考慮すべき属性がいくつかある。DBエンジンによってその属性が異なる

終わりに

Amazon RDSのオンデマンド料金をAWS Price List Query API を用いて取得してみた、という話でした。

DBエンジンによって考慮すべき属性が異なり、汎用的に情報を取得したい場合には工夫が必要ということが分かりました。「オンデマンド料金一括で取りたい」くらいの軽い気持ちで臨んだのですが、深淵の一端を覗いた気持ちになりました。

深淵に足を踏み入れる方の参考になれば幸いです。

以上、チバユキ (@batchicchi)がお送りしました。

参考

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事