杉嵜 諒吾(すぎさき りょうあ)です。戸籍の振り仮名が心配です。
クラウドサービスを使う上でコスト管理は避けて通れない課題です。株式会社PLAYでは主に AWS を用いたシステム構築をしていますが、例えば新しい動画コンテンツが公開された時はシステムへのアクセス数が変動しやすいので、スケーリングなどで変化した AWS のコストを日頃から把握することが特に求められます。今回、AWS のコスト状況をグラフ画像にして Slack に投稿する社内ツール「Budget Falcon」を作りましたので、作った際に考えたことなどを書いていきます。
経緯
弊社 Slack には元々、コストを通知するツールが点在していました。各部署や開発チームが独自に用意したために色々なツールが作られ、それぞれごく一部の範囲で使われていたものです。しかし、どうしても社内ツールにかけられる時間は多くなく、使いにくい状態のまま動き続けていたものもしばしば。
例えば、AWS コンソール上で請求アラートを有効にすると、 CloudWatch Metrics で EstimatedCharges と呼ばれるメトリクスが取得できるのですが*1、取得できるのは月初からの請求額合計です。なので月初は0から始まり、10日の値は月初から10日までのコストの合計値となります。
このメトリクスを画像にしてコスト通知をしていた旧ツールがありましたが、合計金額の変動が見れるだけで1日分のコストは直接わからず、折れ線グラフの傾きで推測せざるを得ません。例えば日次コスト全体が1日で20%上がると普通は大きなコスト変動ですが、折れ線グラフでの視覚的な差は傾きの差となり、変化に気づきにくいです。また月が変われば値も0になってしまうので、月が変わるタイミングでは更に使いにくくなります。
後回しにされがちだった社内ツール改修ですが、とうとう重い腰を上げて、AWSコストを可視化するツールを全社共有で使えるように1つ作ることになりました。
完成品
デフォルトでは毎日朝に、Slack へグラフ画像が投稿されます。グラフ画像を投稿するだけなので似た機能ではありますが、作成するグラフを日次の積み上げ棒グラフにしました。旧ツールの EstimatedCharges のグラフと比べ、1日ごとにコストがまとめられる形となり、1日〜1週間ぐらいの短期的なコスト変動が分かりやすいです。またコストの内訳をサービスごとに分けて表示しているので、どのサービスでコストが変化しているのか明確になります。
このツールですがGitHubで公開しましたので、AWSをお使いの方で利用したい方は是非お使いください。
アーキテクチャ
EventBridge によって定期実行される Lambda 関数が、AWSアカウントごとの料金から積み上げ棒グラフの画像を作成して Slack に投稿します。この時、参照するAWSアカウントと投稿先のSlackチャンネルは Google スプレッドシートで管理しているので、他の社員に編集者権限を与えれば自由に設定を追加変更できます。
スプレッドシートの設定値を見る際は Google Cloud の Workload Identity 連携を使い、あらかじめ作成した Google のサービスアカウントとしてアクセスするので、シートを無制限に公開する必要はありません。加えて Google Cloud のサービスアカウントキーを保存する必要もないので、AWS Secrets Manager などで鍵の管理をする必要もありません。
データとして使用するのは Cost and Usage Report (CUR2.0) で、これを Amazon Athena で分析して使います。Athena の分析エンジンは SQL エンジンをベースとしたものなので、SQL 文を理解しているエンジニアならば、システムで用いる Athena のデータベースで直接分析することもできます。
開発中の工夫
デプロイ・セットアップ方法などはリポジトリのドキュメントを見ていただくとして、ここでは開発時に工夫したことを書いておきます。
固有名詞をつける
「AWSのコスト出るやつ」のままだと、該当するものが多くて他の人と話がしにくいです。AWS の CUR2.0 を指しているのか、AWS コンソールで見れる Cost Explorer のことなのか、予算を超えた時に AWS Budgets から送られてくるメール等の通知なのか、などなど。また無難に「AWSコスト可視化ツール」と言っても、過去に似たようなものが作られているので混同されてしまいます。
なのでプロトタイプを作って早々に「Budget Falcon」という名前を勝手につけました。過去にも社内ツールを作ったことはありますが、今回ちゃんと一意性のある名前を与えることで社内の人たちに周知しやすくなったと感じます。社会に出す製品にしろ社内だけで出すツールにしろ使ってもらわないと意味ないので、名付けは結構効果的でした。
簡単に使えるように
AWSアカウントのIDやSlackのチャンネルIDはスプレッドシートに記載する形にしました。営業職などの非エンジニアも設定できるようにするのと、社内の担当者ならいつでも設定変更できるようにするために、この方法になりました。ツールを管理アカウントに1つデプロイした後は、個別の設定はすぐに終わります。
凡例
複数の要素がある積み上げ棒グラフなので、どの色が何のサービスなのか示す凡例が必要になります。今回、凡例の項目名を決めるためにCUR2.0の line_item_product_code
を用いていますが*2、そのまま使うだけだとちょっと問題があります。
この凡例にある「AmazonES」は Amazon Elasticsearch Service の略称ですが、実際には名前が Amazon OpenSearch Service に変わっているサービスなので*3、OpenSearch に直す必要があります。他にも「awswaf」や「AWSQueueService」といった値も馴染みのある表記に置き換えたいですし、「AmazonS3」の「Amazon」なども削りたいところ。
またパラメータによっては20項目ほどになることもありますが、グラフで20色も使うと、どこかで区別し難い2色になりがちで非常に見にくいです。今回のグラフ生成に用いた matplotlib には20色のカラーマップも有りはしますが*4、なかなか見やすい仕上がりにはなりませんでした。
凡例における項目名と配色の問題を解決するために試行錯誤し、最終的にこうなりました。
項目名については、YAMLファイルで用意したマッピングでシンプルに置き換える形になりました。使ってるサービス分だけ項目を用意する必要がありますが、事前にAthenaで直接クエリを実行して一覧をとり、それらのマッピング生成は GitHub Copilot におおよそ任せたので、あまり時間はかかりませんでした。
また、配色だけで20項目を区別するのは無理だと思ったので、代わりに模様を足して組み合わせで20パターンを作るようにしました。このとき色は、 EC2 や ECS などの Computing は橙色、S3 や EFS は Storage なので緑など、AWS での分類に合ったものに分けるようにし、おおよそどんな性質のコストか判断しやすくしました。
終わりに
既に社内で運用されているツールですが、ツールによる可視化のおかげでAWSコストの問題点が何個か見つかっており、その対応に繋げられています。また見つけた問題の解消による直接的な利益もありますが、毎日見ることによって、自分のコスト意識にも変化があったように感じます。
なお当たり前ですが、ツールを使って定期的にグラフ画像を Slack に投稿しても、都度確認されなければあまり意味はありません。このようなシステム面の整備に留まらず、社内でコスト状況を確認し改善する習慣や体制を作っていけたらと思います。
*1:https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html
*3:Amazon Elasticsearch Service が Amazon OpenSearch Service となり、OpenSearch 1.0 をサポート | Amazon Web Services ブログ
*4:https://matplotlib.org/stable/users/explain/colors/colormaps.html#qualitative