aws pricingコマンドでAmazon RDSのオンデマンド料金を取得してみた
コンバンハ、千葉(幸)です。
最近はAmazon RDSリザーブドインスタンスに興味があります。先日は、AWS CLIを用いて特定リージョン/特定DBエンジンの組み合わせにおいて「実質的な1時間あたりの料金」を一括で取得する方法を試しました。(そこから派生して「期間や支払い方法について購入可能な組み合わせを確認する」というのが本筋のブログになりましたが……)
せっかくなら「オンデマンド料金と比較した実質的な費用節減割合」も一括で取得したくなります。
そうなるとすでに取得方法がわかっている「リザーブドインスタンスの実質的な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つのサブコマンドを使用します。
- describe-services — AWS CLI 2.37.4 Command Reference:フィルタに指定できる属性名を確認
- get-attribute-values — AWS CLI 2.37.4 Command Reference:属性ごとに指定できる値の候補を確認
- get-products — AWS CLI 2.37.4 Command Reference:条件を指定して料金を取得
また、いずれのコマンドも共通して下記のオプションを指定します。
--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というモードがあり、通常のモードと比べてオンデマンド料金が高くなります。
"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)がお送りしました。







