0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Cost Explorer APIで「円換算込み」の月次コスト表を作る — boto3スクリプトと為替の扱い方

0
Posted at

はじめに:なぜ円換算の表が必要か

AWSの請求はUSD建てです。一方で、社内の予算や経営会議の数字は円で動いています。

「先月よりクラウド費用が増えたが、使用量が増えたのか、円安のせいなのか」と聞かれたとき、Cost Explorerの画面(USD(米ドル)表示)だけでは答えられません。

この記事では、Cost Explorer APIで月次コストを取得し、出典を明記した為替レートで円換算して、使用量要因と為替要因を分けて表示する Pythonスクリプトを紹介します。

特にAWSの請求額が大きく、経営会議でも詳細を求められる企業は分析が必要なことが多いため、今回スクリプトを用意しました。(一応、テストはしていますが、何か修正箇所があったり、より良くスクリプトを書く方法があればコメントお願いします)

⚠️ このスクリプトは、Cost Explorer APIで取得したUSD額と、自分で用意した為替レートから推計した円額を出すものです。請求書に記載される円額とは一致しません(理由は後述します)。

前提と必要な権限

  • Python 3 と boto3 が必要です。macOSの場合は次のコマンドでインストールします。
python3 -m pip install boto3
  • 認証情報(aws configure または SSO)が設定済みであること。
  • IAMで ce:GetCostAndUsage が許可されていること。
{
  "Version": "2012-10-17",
  "Statement": [
    { "Effect": "Allow", "Action": "ce:GetCostAndUsage", "Resource": "*" }
  ]
}

注意点が2つあります。

  • Cost Explorer APIは1リクエストごとに課金されます。料金は公式の料金ページで確認してください。月次で1回実行する程度であれば、気になる額にはなりにくいはずです。
  • APIのエンドポイントは us-east-1 です。

API仕様はGetCostAndUsageの公式リファレンスを参照してください。

為替レートCSVを用意する

為替レートはコードに直接書かず、CSVで管理します。こうしておくと、「この数字はどのレートで計算したのか」と聞かれたときに、CSVを見せればそのまま説明できます。

どのレートを使うかに正解はありません。ただし、社内で一度決めたら変えないことが重要です。途中でレートの種類を変えると、月ごとの比較ができなくなります。

スクリプト本体

#!/usr/bin/env python3
"""Cost Explorer の月次コスト(USD)を円換算し、使用量要因と為替要因に分解する。"""
import csv
import sys
from datetime import date

import boto3

FX_CSV = "fx_rates.csv"


def load_fx(path):
    rates = {}
    with open(path, newline="", encoding="utf-8") as f:
        for row in csv.DictReader(f):
            rates[row["month"]] = float(row["usdjpy"])
    return rates


def month_starts(n_months):
    """直近 n_months ヶ月分(当月除く)の月初日を返す。"""
    today = date.today().replace(day=1)
    out = []
    y, m = today.year, today.month
    for _ in range(n_months + 1):
        out.append(date(y, m, 1))
        m -= 1
        if m == 0:
            y, m = y - 1, 12
    return sorted(out)


def fetch_monthly_usd(start, end):
    ce = boto3.client("ce", region_name="us-east-1")
    resp = ce.get_cost_and_usage(
        TimePeriod={"Start": start.isoformat(), "End": end.isoformat()},
        Granularity="MONTHLY",
        Metrics=["UnblendedCost"],
    )
    result = {}
    for r in resp["ResultsByTime"]:
        month = r["TimePeriod"]["Start"][:7]
        result[month] = float(r["Total"]["UnblendedCost"]["Amount"])
    return result


def main(n_months=3):
    fx = load_fx(FX_CSV)
    starts = month_starts(n_months)
    usd = fetch_monthly_usd(starts[0], starts[-1])

    months = sorted(usd)
    print(f"{'month':8} {'USD':>12} {'USDJPY':>8} {'JPY(推計)':>14} {'使用量要因':>12} {'為替要因':>12}")
    prev = None
    for m in months:
        if m not in fx:
            print(f"{m}: fx_rates.csv にレートがありません", file=sys.stderr)
            continue
        jpy = usd[m] * fx[m]
        if prev:
            pu, pr = prev
            usage_effect = (usd[m] - pu) * pr      # 前月レート固定での増減
            fx_effect = usd[m] * (fx[m] - pr)      # 今月USD固定でのレート差
            print(f"{m:8} {usd[m]:12,.2f} {fx[m]:8.2f} {jpy:14,.0f} {usage_effect:12,.0f} {fx_effect:12,.0f}")
        else:
            print(f"{m:8} {usd[m]:12,.2f} {fx[m]:8.2f} {jpy:14,.0f} {'-':>12} {'-':>12}")
        prev = (usd[m], fx[m])


if __name__ == "__main__":
    main(int(sys.argv[1]) if len(sys.argv) > 1 else 3)

実行方法:

python3 cost_jpy.py 3

サービス別の内訳も見たい場合は、get_cost_and_usage に GroupBy=[{"Type": "DIMENSION", "Key": "SERVICE"}] を追加します。その場合は r["Groups"] を集計する形に書き換えてください。

出力の読み方:使用量要因と為替要因を分ける

出力イメージは次のとおりです(値はダミーです)。

month USD USDJPY JPY(推計) 使用量要因 為替要因
2026-07 XXX XXX XXX - -
2026-08 XXX XXX XXX XXX XXX
  • 使用量要因:前月のレートで固定したと仮定した場合の、USD額の増減による円換算での差額です。
  • 為替要因:今月のUSD額を固定し、レートだけが動いたことによる差額です。

この2つを足すと、前月との円額の差に一致します。経営層への説明では、この2列を並べるだけで「増えたのは使用量なのか、為替なのか」に答えられます。

注意点:請求書の円額とは一致しない

ここは誤解されやすいので、はっきり書いておきます。このスクリプトで出る円額は社内説明用の推計値です。経理が照合する請求書の円額の代わりにはなりません。主な理由は次の3つです。

  • 円建てで支払う設定にしている場合、AWS側で適用される為替レートは、自分でCSVに用意したレートとは別物です。
  • UnblendedCost の値は、税・クレジット・返金の扱いによって請求額と差が出ることがあります。
  • 当月分は確定前の値です。前月分も、月初直後はまだ動く可能性があります。

経理と数字を突き合わせる場合は、請求書を正としてください。そのうえで、このスクリプトは増減の理由を説明するための道具として使い分けるのがおすすめです。

請求代行・Organizations環境での注意

Organizations配下のメンバーアカウントや、請求代行(リセラー)経由の契約では、Cost Explorerの表示範囲やAPIの利用可否が、管理アカウント側の設定や契約形態によって制限される場合があります。スクリプトが空の結果を返したりエラーになったりした場合は、まず自分のアカウントからCost Explorerがそもそも見える状態かを確認してください。

技術的に確認すべき点は、以前の記事「AWS Organizationsを使ったまま請求代行を検討する時の技術チェックリスト」にまとめています。

まとめ

  • Cost Explorer APIを使えば、月次のUSDコストは数行のコードで取得できます。
  • 為替レートは出典付きのCSVで管理し、使用量要因と為替要因に分けて表示すると、社内で説明しやすくなります。
  • ただし、算出した円額はあくまで推計値です。請求書の円額とは別物として扱ってください。

円安の影響そのものを抑える方法については、クラウドコストのブログでも整理しています。


参考:

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?