ClaudeでAWSのコスト急増を調べる — Cost ExplorerのCSVを使用タイプまで分解
Cost ExplorerのCSVをClaude Codeに渡し、サービス別、使用タイプ別の順に前月差を分解してNAT Gateway、データ転送、CloudWatch Logsなどの原因候補に絞る手順です。
AWSの請求が先月より跳ね上がったとき、最初に要るのは「どのサービスの、どの種類の使用量が増えたか」です。Cost ExplorerのCSVをClaude Codeに渡すと、この絞り込みを3段に分けて短時間で回せます。サービス別、使用タイプ別、リージョンやアカウント別の順です。
この記事は、CSVの出し方、渡す前の権限設定、前月差の寄与を出すスクリプト、使用タイプを典型原因に当てる表までを順に扱います。AWSのAPIには一度も触れないので、Cost Explorer APIのリクエスト課金も発生しません。
急増の調査は3段で絞る
Cost Explorerは、請求の元データと同じデータセットから作った画面です。直近13か月までの日次・月次データを見られ、コスト配分の軸として「サービス」「使用タイプ」「リージョン」「リンクアカウント」などで絞り込めます。
急増の原因を探すときは、いきなり細部を見ずに粗い軸から順に絞ります。
急増の原因に届くまでの3段
- 1
サービスで分ける
月次、グループ化「サービス」で直近2か月を出します。前月差が最も大きいサービスを1〜2個に絞ります。
- 2
使用タイプで分ける
絞ったサービスだけをフィルターに入れ、グループ化を「使用タイプ」か「使用タイプグループ」に替えて出し直します。時間課金なのか、処理量課金なのかがここで分かれます。
- 3
リージョンとアカウントで分ける
増えた使用タイプだけを残し、リージョン、リンクアカウント、タグの順に切り口を替えます。どの環境の変更かがここで見えます。
CSVは各段で1枚ずつ出します。1枚に全部を詰めたCSVより、段ごとのCSVの方がClaudeが読み違えにくく、集計の根拠も追いやすくなります。
Cost ExplorerからCSVを3枚出す
Cost Explorerの画面は無料で使えます。レポート画面には、グラフの元になったデータをCSVでダウンロードする機能があります。出す前に、次の仕様を押さえておきます。
- 表示できるのは当月と直近13か月までです
- 反映は前日分までで、当月の数字は後から更新されることがあります
- 時間の区切りはUTCです
- 金額は米ドル表示です
- 時間単位の粒度は、管理アカウントで有効化した場合のみ使えます。見られるのは直近14日間です
月の途中に調査するなら、月次の比較だけでなく日次の粒度も1枚出しておきます。急増が月の何日から始まったかは、日次でしか分かりません。
出す3枚の条件は、次のとおりです。
| 枚 | 期間と粒度 | グループ化 | フィルター |
|---|---|---|---|
| 1枚目 | 期間と粒度先月と今月、月次 | グループ化サービス | フィルターなし |
| 2枚目 | 期間と粒度同じ期間、月次 | グループ化使用タイプグループ | フィルター1枚目で増えたサービス |
| 3枚目 | 期間と粒度急増の期間、日次 | グループ化リージョンかリンクアカウント | フィルター2枚目で増えた使用タイプ |
ファイル名は 01-by-service.csv のように段の名前を付けて、プロジェクト内の専用ディレクトリに置きます。リンクアカウント別に出したCSVにはアカウント単位の請求額が入るため、このディレクトリは .gitignore に入れておきます。
コンソールの比較機能で先に当たりを付ける
Cost Explorerには、2か月の費用を比較して増減の大きいサービス、アカウント、リージョンと、その要因を示す機能があります。コンソールのホームにはTop trendsウィジェットがあり、直近2か月の変動上位10件が出ます。Cost Explorerの画面では、レポートパラメーターのパネルから「Compare」を選びます。この機能に追加料金はかかりません。
CSVを作る前にここで増えたサービスの見当を付けておけば、1枚目の確認が早くなります。比較機能のAPIを使う場合に必要な権限は ce:GetCostAndUsageComparisons と ce:GetCostComparisonDrivers です。
Claude Codeに渡す前に権限を決める
CSVを読ませるだけなら、Claudeに必要なのはファイルの読み取りと、集計スクリプトの実行です。AWSのコマンドは要りません。そこで、aws コマンドを通さない設定にしておきます。
{
"permissions": {
"deny": [
"Bash(aws *)"
],
"allow": [
"Read(./cost-data/**)",
"Bash(python3 scripts/diff_cost.py *)"
]
}
}これを .claude/settings.json に置きます。ルールはdeny、ask、allowの順に評価され、先に一致した結果が採用されます。Bash(aws *) のdenyは、後から別のallowを足しても aws で始まるコマンドを止め続けます。調査の途中で「ついでにCLIで確かめて」と頼まれても、請求データの外へ出ない構成です。
注意が1点あります。Bashのルールは、Claudeが書いたコマンド文字列に対して一致します。aws を別の経路で呼ぶ書き方までは、このルール1本では塞げません。AWS認証情報そのものを、この調査を行うシェルに置かないのが確実です。
権限ルールの書き方と評価順は、/permissionsコマンドの解説にまとめています。
前月差の寄与を出す
1枚目のCSVから、サービスごとの前月差と全体の増加に占める寄与率を出します。計算をClaudeの暗算に任せず、スクリプトに固定します。数字の誤りは請求の調査では致命的です。コードで行わせれば、同じ入力から同じ結果が出て検算もできます。
import csv, sys
path, prev_col, curr_col = sys.argv[1], sys.argv[2], sys.argv[3]
top = int(sys.argv[4]) if len(sys.argv) > 4 else 10
with open(path, newline="", encoding="utf-8-sig") as f:
table = list(csv.reader(f))
# 期間が列の向きなら、そのまま使う。期間が行の向きなら転置する
if prev_col not in table[0]:
table = [list(col) for col in zip(*table)]
if prev_col not in table[0] or curr_col not in table[0]:
sys.exit(f"列名 {prev_col} / {curr_col} が見つかりません。先頭行: {table[0]}")
header = table[0]
pi, ci = header.index(prev_col), header.index(curr_col)
def num(cell):
return float(cell.replace(",", "") or 0)
rows = []
for r in table[1:]:
key = r[0]
if "total" in key.lower():
continue # 合計行は寄与の計算から外す
prev, curr = num(r[pi]), num(r[ci])
rows.append((key, prev, curr, curr - prev))
total_delta = sum(r[3] for r in rows)
print(f"{header[0]},前月,当月,差額,差額の寄与率")
for key, prev, curr, delta in sorted(rows, key=lambda r: -abs(r[3]))[:top]:
share = delta / total_delta * 100 if total_delta else 0
print(f"{key},{prev:.2f},{curr:.2f},{delta:+.2f},{share:.0f}%")このスクリプトは scripts/diff_cost.py に保存します。引数で指定した2つの期間を比較対象として読みます。CSVの向き(期間が列か、期間が行か)と列名は、出力の設定によって変わる場合があります。向きが逆でも動くよう、スクリプトは期間名が先頭行に無ければ転置してから集計します。合計行は、名前に「total」を含む行として外します。先にClaudeに先頭数行を読ませて、向きと列名、合計行の名前を確認させます。
cost-data/01-by-service.csv の先頭5行を読んで、列名、期間が行か列かの向き、合計行の名前を教えて。
そのあと scripts/diff_cost.py を、先月と今月の列名を指定して実行して。
結果の表をそのまま貼って、増加の上位3つだけコメントして。架空の数字で出力を示すと、次のようになります。
Service,前月,当月,差額,差額の寄与率
Amazon EC2,300.00,780.00,+480.00,77%
Amazon CloudWatch,100.00,230.00,+130.00,21%
Amazon S3,200.00,210.00,+10.00,2%この例では、増加分の98%を2サービスが占めています。次はEC2に絞った2枚目へ進みます。寄与率が1〜2サービスに偏らず、多数のサービスに分散して増えている場合は、特定の障害ではなく全体の利用増である可能性を先に疑います。
使用タイプを典型原因に当てる
2枚目のCSVでは、使用タイプグループの行名が原因候補への入口になります。Cost Explorerの使用タイプグループには、調査でよく当たる名前が揃っています。
| 使用タイプグループ | 計っているもの | 増えたときの見立て |
|---|---|---|
| EC2: NAT Gateway - Running Hours | 計っているものNAT Gatewayが稼働した時間 | 増えたときの見立てNAT Gatewayの台数や稼働期間が増えた |
| EC2: NAT Gateway - Data Processed | 計っているものNAT Gatewayが処理したGB数 | 増えたときの見立てNAT経由の通信量が増えた |
| EC2: Data Transfer - Inter AZ | 計っているものAZをまたぐ転送のGB数 | 増えたときの見立てAZ間の通信が増えた |
| EC2: Data Transfer - Internet (Out) | 計っているものAWSの外へ出ていく転送のGB数 | 増えたときの見立て外向きの通信が増えた |
NAT Gatewayは、稼働している時間と処理したデータ量の両方に課金されます。同じNAT Gatewayでも、時間側が増えたのか処理量側が増えたのかで、疑う先が変わります。
時間側が増えたなら、NAT Gatewayそのものが増えています。AZごとに作った、検証用に作ったまま残っている、といった変更を探します。
処理量側が増えたなら、NAT Gatewayを通る通信が増えています。リソースとNAT Gatewayが別のAZにあるとAZ間転送の料金がかかります。AWSサービス向けの通信が多い場合は、インターフェースエンドポイントかゲートウェイエンドポイントを検討できます。
CloudWatch Logsの急増は、別の見方をします。料金は、取り込み(Collect)、保管(Store)、クエリ(Logs Insightsなどのスキャン量)に分かれています。急増したのがどの課金軸かで、対処が変わります。
- 取り込みが増えた場合: ログの出力量が増えています。デバッグログの有効化やコンテナログの増加が代表的です。Container Insightsは、ログ1行ごとに700バイトのメタデータを加えます
- 保管が増えた場合: 保管するデータ量が増えています。ロググループの保持期間の設定を見直します
- クエリが増えた場合: Logs Insightsのスキャン量が増えています
CloudWatchからのデータ転送(Data Transfer OUT)は、EC2のデータ転送料金と同じ表で課金されます。ログをリージョンの外に出している構成では、ここも確認対象です。
切り分けの順番
使用タイプまで絞れたら、Claudeに次の順で質問を出させます。順序が大事なのは、費用の増え方によって、次に見るデータが別になるからです。
使用タイプが増えたときの切り分け
- Q増えたのは時間課金の行(Running Hours)か?答えが処理量や転送量の行が増えています。次の問いへ進みます答えがはい
稼働しているリソースの数が増えています。3枚目のCSVをリージョンとリンクアカウントでグループ化し、どの環境で台数が増えたかを見ます。
- Q増えたのはAZ間転送(Inter AZ)の行か?答えがインターネット向け転送、またはサービス固有の処理量を疑います答えがはい
構成の変更でAZをまたぐ通信が増えた可能性があります。デプロイや配置の変更日を、日次CSVの立ち上がりの日と突き合わせます。
- Q立ち上がりの日に、リリースや設定変更があったか?答えが外部要因、たとえば利用者の増加やバッチの追加を疑います答えがはい
その日の変更履歴を、Claudeに読ませる原因候補の根拠にします。突合の進め方は変更カレンダーとの突合手順と同じ形です。
原因候補を1〜2個に絞って、人が確認する
Claudeが出すのは「請求データの上で何が増えたか」までです。なぜ増えたかは、構成の変更履歴とリソースの実態を見てから決めます。
数字を読み違えやすい3つの場面
CSVの調査で誤りが入りやすいのは、次の3つです。
落とし穴
月の途中の数字を前月の全体と比べている
当月分は前日までの数字で、日数も月末より少なくなります。月初から数日で「前月より低い」と読むのも、月末直前に「前月に迫った」と読むのも、日数が違うまま比べています。月途中の調査は、日次CSVで同じ日数分を並べます。
落とし穴
割引や返金の動きを使用量の増加と取り違える
Cost Explorerには、未ブレンド、償却後、割引後など、金額の見せ方がいくつかあります。日次の未ブレンドコストは返金を含みません。使用量が増えていないのにコストだけ動いて見えるときは、請求の種類(Charge type)で絞って、割引や調整の行を外して見直します。
落とし穴
Claudeに原因まで断定させている
CSVに載っているのは金額と使用量だけです。NAT Gatewayの処理量が増えたことは分かっても、どのアプリの通信かは載っていません。依頼文に「原因を断定せず、CSVから言えることと、追加で確認が要ることを分けて書いて」と入れておくと、推測が事実として並ぶのを防げます。
APIで取りに行くか、CSVで済ませるか
CSVを手で出す方式は、毎月の定例調査には向きません。出す枚数が増えるほど手間も増えます。定期的に回すなら、Cost ExplorerのAPIを呼ぶMCPサーバーを使う選択肢があります。ただしAPIは、ページ付きのリクエスト1回ごとに0.01ドルが課金されます。画面の利用は無料です。
手元の1回きりの調査ならCSV、毎月の定点観測ならMCPサーバーという分け方になります。接続の手順と読み取り専用IAMの絞り方は、AWS Billing MCPサーバーの接続手順で扱っています。
まとめ
急増の調査で大事なのは、Claudeに「原因を当てさせる」のではなく、「どこまで絞れたか」を毎段階で確認することです。サービス、使用タイプ、リージョンの順にCSVを分け、集計はスクリプトに固定し、aws コマンドは通さない。この3点を守れば、請求データの範囲内で安全に原因候補まで進めます。最後の「なぜ増えたか」は、変更履歴を見て人が決めます。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。
- docs.aws.amazon.com/cost-management/latest/userguide/ce-what-is.html
- docs.aws.amazon.com/cost-management/latest/userguide/ce-filtering.html
- docs.aws.amazon.com/cost-management/latest/userguide/ce-cost-comparison.html
- docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-pricing.html
- aws.amazon.com/cloudwatch/pricing
- code.claude.com/docs/en/permissions