チーム・サブシステム単位で見るAWSのコスト可視化方法（コスト配分タグ＋Cost Categories+ Cost Explorer）

## はじめに
AWSで自分のチームや担当システムでかかったコストがどれくらいか？を知るためのコスト可視化方法について紹介します！紹介する内容は、設計したタグをコスト配分タグにした上でCost CategoriesでグルーピングしCost Explorerで確認できるようにする、というもので最終的なコスト可視化の画面は以下のような感じです。

開発プロジェクトの性能テストで以下のような要件があり、任意で決めた単位のコスト可視化方法を検討したので、実際に実装したコスト可視化方法について記載していきます。**ただ、実装後に気づいた失敗もあったので最後に失敗についても紹介します。(各パートで失敗と感じた箇所は太文字にしてます)**
1. Organaizationsで管理している各AWSアカウント毎、各プロダクト毎、各担当チーム毎といった任意の単位でかかったコストがどの程度かをさっと可視化したい
2. 今後のコスト可視化の工数軽減のためにも、エクスポートしたcsvファイルをやりくりしてグラフ化するといった手間は出来るだけ避けたい
3. コストは構築チームだけでなくお客様の担当者も操作するため、出来るだけ簡単に表示したい

## 使用するAWSサービス

今回使用するAWSサービスは全部で4つあり、タグ以外は[Billing and Cost Management(請求とコスト管理)]の機能です。最初にタグ、コスト配分タグ、Cost Categoriesの位置付けを図にしたもの載せておきます。
 ![スクリーンショット 2024-11-27 0.12.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/f07e9dc2-052a-0a6a-c19c-7e311046849c.png)

- タグ
    - AWS リソースを整理するためのメタデータとして機能するキーと値のペア
    - 今回使用するCost Explorerではディメンションを指定する際にただのタグは選択ができないため、以下で紹介するコスト配分タグ or Cost Categoriesを使用する必要がある
- コスト配分タグ
    - 実態は上記のタグで、Cost Explorerやコスト使用状況レポートの明細で、タグ別に料金を表示するために利用されるラベル
- Cost Categories
    - ルールを定義し、アカウントやコスト管理タグなどをグルーピングするサービス
    - チーム単位やシステム単位などの、ユーザ側の組織やシステム単位でルール定義しグルーピングするには、デフォルトで用意されてるルール（アカウントやAWSサービス）では不十分なためコスト管理タグを利用する（ただのタグはルールとして選択できません）
- Cost Explorer
    - コストと使用量を表示および分析できるAWSサービス
    - AWSコンソールで好きな条件でグラフ化をすぐにでき、コストのレポートも出力できるためAWS使ってる人なら馴染み深いサービスかなと

## コスト可視化方法の内容
**1. タグ設計をする**

まずはAWSリソースにつけるタグのキー&値をどうするか決めていきます。コスト可視化目的のタグの設計ポイントは、最終的にどの単位でコストを可視化したいかをこの時点で決め切ることだと思ってます。簡易版ですが以下に実際のタグ設計内容を添付しておきます。
![スクリーンショット 2024-11-24 23.00.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/919b39ee-613a-c434-452c-3ea31791ca76.png)

基本的にコストを確認したいタイミングは、月次とかの定期確認や、異常なコスト増加を検出した時の原因特定・改善する時だと思います。異常なコスト増加の際は、特に大規模プロジェクトだとプロダクト毎にチームが分かれてると思うので、知りたいのはコスト増加している犯人がどのプロダクト、さらにはどのサブシステムか、どのAWSリソースかの原因特定だと思います。

 そのため、タグを設計するときは【プロダクト毎】【担当チーム毎】【サブシステム毎】といった分類で設定した方がよく、タグ設計でも各単位が分類できるようにする必要があります。（補足ですが、上記の設計例は元々Cost Categories利用を想定していない別担当者がコスト用のタグとして事前設計したもので最適ではないです。例えば【AWSサービス】については最終的な可視化で用いるCost Explorerのデフォルト機能で分類できるため、Cost Categories利用を見据えるとタグの値に含める必要はありません。**ここでの設計が実装後に気づいた失敗に繋がります。**）
 
**2. AWSリソースに設計したタグをつける**

設計したタグをAWSリソースに付与していきますが、チーム毎で各々がAWSリソースを作成している場合は、各チームにタグ設計を共有し適切に設定してもらうよう啓蒙する必要があります。Terraform等のIaCで管理している場合はコードでタグ付けも簡単にできますが、もし手動でAWSリソースを作成している場合はタグエディタで複数のAWSリソースのタグ情報を修正するのも手だと思います。（IaCで管理している場合はタグ情報が上書きされる恐れもあるため、各チームへの啓蒙が面倒でも手動対応はNGとして各チーム担当者に実施してもらうのがベターだと思います。）

名称等は変えてますが、上記のタグ設計を基に付与したタグを一部紹介します。上記のタグ設計だと、例えば「012345678910というAWSアカウント内の会計システムの決算処理で使用するEC2」のcost-allocationタグには「012345678910_01_01_00_001」という値を設定しますが、**各単位の番号と実名を紐づける必要があり、設定ミスも起こりやすく非常に読みづらいタグとなっています。**
![スクリーンショット 2024-11-26 0.06.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/da1997b3-042d-2650-f817-bc67041aade0.png)

**3. コスト配分タグとして有効化する**

次は上記で設定した「cost-allocation」タグをコスト配分タグとして有効化させます。コスト配分タグとして有効化させるには[Billing and Cost Management(請求とコスト管理)]>[コスト配分タグ]の画面までいき、有効化したタグを選択して右上の[有効化]を押下します。今回だと「cost-allocation」タグをコスト配分タグとして有効化したいのでこちらを選択します。
![スクリーンショット 2024-11-27 0.27.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/a2adf59b-fd6f-d228-2ddc-e74bce211d23.png)
 
そうすると24時間以内にコスト配分タグとしてステータスがアクティブとなりますので、コスト配分タグの有効化自体はこれだけて完了です。**ただし、AWS Organaizationsで管理しているAWSアカウントでは、このコスト配分タグの有効化は支払いアカウントである組織管理アカウントでしか操作できないため、社内もしくは社外の担当者に実施してもらう必要があるためリードタイムが発生する場合もあります。**

**4. Cost Categoriesでルール設定する**

次は有効化したコスト配分タグをグルーピングするためにCost Categoriesの設定をしていきます。[Billing and Cost Management(請求とコスト管理)]>[Cost Categories]で作成する画面まで遷移した画面は以下で、設定が必要な箇所を赤枠で示しているのでそれぞれ見ていきます。
![スクリーンショット 2024-11-29 19.52.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/55364201-6280-cda3-99b8-55313fe19fcd.png)


実際にタグ設計した単位毎にCost Categoriesでグルーピングの設定まで落とし込むために、上記画面と最初の設計を照らし合わせた簡易表を以下に掲載します。先ほども少し書きましたが、タグ設計で用意していたAWSサービスはCost Explorerのデフォルト機能で分類可能なためグルーピング設定はしてないです。（後にCost Explorerで表示する際に説明します）このパートではこの表のNo.1〜No.3の「プロダクト区分」の設定をしていきます。
![スクリーンショット 2024-11-29 0.29.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/b65b5636-1889-4e7a-8b77-db774a87e92f.png)


まずは左上赤枠[自分のコストカテゴリ]という箇所を編集し、今回のCost Categories名称を決めます。その後[ルールを追加]を押下し、右下赤枠[次に、コストを次のようにグループ化します]でルール名を入力します。ここで設定したルール名が、Cost Explorerで可視化した際にグラフで色分けして表示されます。

次に[ディメンション][演算子][value]でルール名に即した設定をしていきます。[ディメンション]ではOrganaizationsで管理してるAWSアカウント、EC2やLambdaといったAWSリソース等も選択できますが今回は作成したコスト配分タグを選択します。[演算子]では[value]に対して完全一致や含まない等の条件を選択できますが、**ワイルドカードといった正規表現は使用できませんので注意が必要です。（ここが今回の最も失敗した部分でした）**

この後にも[コストを分割]と[その他の詳細を追加]という画面が出ますが、今回の要件1.である「コストをさっと確認したい」いう面では不要な設定だったため無視をし、設定せずにそのまま先に進みます。

ここまでで「プロダクト区分」の中でもNo.1の設定が終わりになります。続いてNo.2とNo.3も同様手順で設定したものが以下となります。さらっと[未分類のコスト]という箇所に「その他」と記載してますが、設定したルール名に該当しないものは全て「その他」に分類されてCost Explorerで表示されるようになります。
![スクリーンショット 2024-11-28 0.15.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/8c1c05d3-7ba5-e84c-e67c-2fe228d5a541.png)

そしてNo.4〜No.10の「サブシステム区分」も設定すれば、Cost Categoriesのホーム画面では以下のように表示されます。コスト配分タグの有効化と同様に24時間以内にステータスが適用済みになりますので、これでCost Explorerで表示する準備が整いました。
![スクリーンショット 2024-11-28 0.23.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/56a3f376-e57e-5a8a-5c00-40a7538d8c5b.png)

**5. Cost Expolrerで確認する**
ここからがCost Expolrerでのコスト可視化についてです。[Billing and Cost Management(請求とコスト管理)]>[Cost Explorer]の画面までいき、右サイドバーの[ディメンション]で「Cost Category」、Cost Categoryの中でも先ほど設定したCost Categories名称を選択します。
![スクリーンショット 2024-11-29 8.54.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/a70cacb9-90ed-e7fa-1ca3-630b3b9afeb1.png)

上記の画像ではCost Categories名称に「プロダクト区分」を選択したため、上記グラフでは【11月に発生したコスト全体の中で、プロダクト毎のコスト】が見れています。
さらにどのサブシステムでコストがかかったかを確認するには、Cost Categories名称に「サブシステム区分」を選択します。
![スクリーンショット 2024-11-29 9.01.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/ec87fb51-a996-2db0-2530-98dbacb86265.png)

上記グラフ上では【11月に発生したコスト全体の中で、サブシステム毎のコスト】が見れています。（※業務で使用している名称などを載せないよう、今回のブログ用に名称をカスタマイズした関係でプロダクト区分とサブシステム区分の料金で整合性が取れてませんが金額は気にしないでください）
そして、プロダクト毎やサブシステム毎で、どのAWSリソースがコストかかっているかを確認するには少しだけ違う操作をする必要があります。
![スクリーンショット 2024-11-29 9.09.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935139/0618fe54-098f-f727-1f8b-e5830efc4b85.png)


上記グラフでは【11月に発生したプロダクト区分の販売管理の中での、AWSリソース毎のコスト】が見れています。この条件を満たすために今回は[ディメンション]だけでなく[フィルター]も使っています。[フィルター]はその名の通り表示されるコストを制限して条件に合致するものだけをグラフ化させます。Cost Explorerで【XXXXの中での、◯◯◯◯のコスト】を見たい時は、XXXX は[フィルター]、◯◯◯◯ は[ディメンション]で設定すれば想定通りに表示されると思います。

Cost Explorerを触っていると気づくと思いますが、「タグの設計次第ではCost Categoriesでグルーピングしなくても、コスト配分タグを[ディメンション]に設定したらコスト上手く見れるんじゃない？」と思うかもしれません。
確かにコスト配分タグでもやりたいことは実現できると思いますが、今回は要件3.である「お客様の担当者も操作するため、出来るだけ簡単な操作で表示したい」を実現させるのにCost Categoriesを使用したかったです。
Cost Categoriesでグルーピングすると日本語で誰もが分かりやすい名称（上記の販売管理や会計_仕訳等）がCost Explorerで表示されるため、認知負荷を下げられるというメリットがあると思っています。
コスト管理タグはあくまで実態がタグでvalueに入るのは基本英数字のため、Cost Explorerで選択すると多少の脳内変換が必要です。
類似した英数字の並びがあると間違える恐れもあるため、誰が触っても使いやすいようにするという意味でCost Categoriesでグルーピングしておくのは良いと感じています。

## 気づいた失敗
ここまでで業務で実施したコスト可視化方法を紹介しましたが、やっているときに気づいた失敗について書いていきます。
- タグの設計がいけてなかった
    - タグについてですが、元々Cost Categoriesを想定したタグになってなかったため不要な内容も記載しており、無駄にタグが長くなってしまいました。
    - プロダクト区分・サブシステム区分・AWSリソースと、数字との対応をおさえる必要があるため、タグ単体で見るとかなり見にくいタグになっています。
- コスト配分タグ、Cost Categoriesの有効化や設定にリードタイムを取られた
    - Organaizationsで管理しているAWSアカウントだと、上記操作は組織管理アカウントでしか操作できず、Organaizations使用している場合は大抵がプロダクトとかではなく、社内もしくは社外のクラウド管理者とか別担当者がいるためどうしても依頼が必要。
    - 別担当者に依頼するということで、何がしたいか等を説明する必要があったり、作業依頼のための申請や追加作業費用なんかの話にもなるため、事前に確認しておいたほうがいい
- Cost Categoriesのルールで正規表現が使用できない
    - これが一番大きかったのですが、Cost Categoriesで[ディメンション][演算子][value]によってルールを作成するときに、[value]で正規表現が使用できないようでした。（AWSサポートへの問い合わせたところはっきりとは言われてませんが、調べたり実践しても正規表現は認識されなかったので、無理そうだなと思っています。）
    - Organaizationで管理している場合だと、組織管理アカウントで設定したCost Categoriesは全てのAWSアカウントで共用されます。そのため、今回のタグ設計だと【AWSアカウントID】がタグの値に組み込まれており、正規表現が使えないとCost Categories名称の「プロダクト区分」「サブシステム区分」をAWSアカウント毎に作成する必要があり、場合によってはかなりの数のCost Categories名称を作成する必要があります。（「012345678910_プロダクト区分」、「98765432100_プロダクト区分」といった感じで）
    - 上記を踏まえると、そもそものタグ設計、1つのコスト配分タグに対してvalueに全ての分類要素を詰め込まず、分類要素毎にタグを一つ一つ設定し、Cost Categoriesでルール名作成するときにそれらのタグを複数ルール指定すればより柔軟に設定できると感じました。

## まとめ
今回は、コスト配分タグ＋Cost Categories+ Cost Explorerを使用し、任意の単位毎で見るAWSのコスト可視化方法について書きました。
実際やったことはたかだかタグをつけ、少し設定をしただけではありますが、コスト管理目的でなくてもタグ設計は少なからず考える機会はあるはずなので、同じような要件があれば考慮いただければと思います。