AWSの費用予測を少しだけ解決した話

こんにちは。株式会社TRYTで開発業務丁稚奉公修行中のhollyroyal-teaと申します。 紅茶好きのような名前ですが、紅茶よりコーヒーを愛する人です。

本日はクリスマス恒例のアドベントカレンダー用に記事を書き起こしてみました。

そんなクリスマスのお題ですが・・・

それは

開発費用の将来予測を精緻化したい!

そんな背景と解決のためのこねたを少し書き連ねていきます。

弊社は医療・福祉等に特化した人材紹介ビジネスを展開しており、12月1日に既存の医療・介護領域の人材紹介サービスを統合した「TRYTワーカー」をローンチいたしました。

tryt-worker.jp

サービス開発の基盤部分はAWSを全面的に採用しており、上記サイトもAWSを基盤に構成しています。 前職はオンプレでやっていたので、今更ながらAWSの凄さに驚きながら開発に参画しているわけですが、開発が進むに連れて、 リソースの見直しや当初想定していなかった追加利用など発生したり、そのための開発環境を準備していたり・・・

などなど、気づくと以前の2倍近くに!従量課金の怖みですね。

(費用爆あがりのイメージです) よいサービスを開発するために当然かかるものなので気づいたところで仕方ないのですが、

「予算が毎月オーバーしているのだけど?」

と上司からもつっこまれる日々。

という経緯があり、AWSコンソールで、毎日現在の利用額を確認しよう。という話になったのですが、 どうせなら、普段使っている業務上のツール(弊社の開発陣はみんな大好きなslackを採用しています)で見れるようにしたいので、Lambdaで通知する仕組みを作ることにしました。

・・・ここまではありきたりな話ですが、

  • 毎月、予算枠に収まるのか?
  • 予算を超えそうなら早めに見込みを修正したい

というニーズが出てきそうなので、その月の現在の利用額だけでなく、月末の予想額も知りたくなります。

予想できるの?と思われた皆様。AWSコンソールにログインした直後の画面を思いだしてください。

予測される月末のコスト と表示されているのを知っていましたか?(業務の都合上、金額は伏せておりますが・・・) この値も取得して、slackに通知したいと思います。

PythonでLambdaを実行するようにしたいので、PythonAWSの各種機能を利用できる boto3 を利用します。 大体のことが実行できるため、マニュアルの充実さが尋常じゃないです。その中からCost Explorerに関する部分を探してみたところ、

boto3.amazonaws.com

Cost Expolorerの機能にget_cost_forecastというメソッドがあります。 名前的にもこれで取得できそうな雰囲気です。それでは簡易なスクリプトを書いて確認してみます。

gistdd3e61bb22354bb6a7e725884b49b7ac

TimePeriodに指定するStartの値は実行する当日までの費用は確定済みなので翌日を指定するようにしました。 Endは月末を指定しがちですが、翌月1日になるように指定しています。 おそらく仕様通りの指定方法と思われますが、これで当月の月末までの予想コストが取得できそうです。

MetricはUNBLENDED_COST(非ブレンドコスト)を選択しましたが、以下の記事の説明がわかりやすかったです。あくまで予測なので乖離が大きければBLENDED_COSTにして精度が高い方を選べば良いでしょう。 このあたりは以下を参考にしました。

hero-rin.hatenablog.com

結果は・・・

forecast is USD XXX,XXX.XX

(都合上金額をお見せできないので、出力内容を見ても何のことだか・・・と思われそうですが)、得られた出力内容とAWSコンソールの予想コストの値はあっています。 ただし、これだけでは上司のニーズを満たすことはまだまだ道半ばです。

「ドルの予想額は分かったけど、何円になるの?」

・・・そうですね。ドルではなく何円になるかは当然気になるところです。昨今の円安も費用高騰の大きな要因なのでそりゃそうです。

とはいえ、金融系の有料サービスやスクレイピングでもしないとレートなどわからないのでは?と思いきや

openexchangerates.org

便利なサービスがありました。為替レートの情報を取得したり、計算できるAPIが揃っています。

docs.openexchangerates.org

ドキュメントにも取得方法が記載されているので、さっそく利用してみました。登録方法は便宜上割愛しますが、APIキーを取得し、以下で確認してみたところ

$ OPENEXCHANGERATES_APP_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
$ curl -sfL  "https://openexchangerates.org/api/latest.json?app_id=$OPENEXCHANGERATES_APP_ID"
{
  "disclaimer": "Usage subject to terms: https://openexchangerates.org/terms",
  "license": "https://openexchangerates.org/license",
  "timestamp": 1671379223,
  "base": "USD",
  "rates": {
   .
   .
   .

    "JMD": 154.018553,
    "JOD": 0.7093,
    "JPY": 136.70502628, ## ここ
    "KES": 123.465627,
    "KGS": 84.95,
   .
   .
   .
  }
}

JPYの値が日本円の最新のレートのようです。boto3で取得した予想コストを掛け合わせれば、日本円でだいたいどれぐらい払うのかも計算できそうです。

ということで、これまでの試行錯誤した内容のまとめは以下になります。

gist960644c383d250253bfd949c5edb3e0b

コードが出来上がりました。あとはLambdaを定期的に実行するため、

  • CostExplorerの情報を参照するロールを作成

  • Lambdaを作成し、上記ロールをLambdaに付与

  • コードを反映する

  • 適切な環境変数を設定(OPENEXCHANGERATES_APP_IDとSLACK_WEBHOOK_URLを環境変数に仕込んでいます)

  • EventBridgeで毎日定時に実行されるように設定

税込金額になってしまいますが、それらしい金額が通知されるようになります。

これで毎日の金額の把握の精度が格段にあがります。都度報告しなくても金額の把握もできるようになりました。ちゃんちゃん♪

・・・ということで、これ以外にもコスト精緻化の取り組みを絶賛継続中なので、ねたが溜まったら記載することにいたします。

補足: CostExplorerをLambdaから参照可能にするためのポリシーです。

gist83756ff83dd96e028df7ce72151ed03a