たまにはピンポイントで呼び掛けてみたいのです
안녕하신게라!パナソニック コネクト株式会社クラウドソリューション部の加賀です。
この記事を開いたあなたは、おそらくAWS Organizationsの管理メンバーで、かつ、こんな悩みを抱えているのではないでしょうか。
- 「Organizationsの請求額、どうやって社内の部署やプロジェクトに割り振ってる?」
- 「コスト配分タグは付けた。でも共有リソースの費用按分が面倒…」
- 「RIやSavings Plansの割引額、どうやって公平に分配すれば経理に怒られない?」
- 「結局、毎月Cost Explorerの画面をスクショしてExcelに手打ちしてる…」
もし一つでも当てはまったなら、ご安心ください。あなたは一人ではありません。日本に数十人もいないかもしれない、AWS Organizationsの社内費用処理という深く暗い沼のほとりで、同じように途方に暮れている仲間が、ここにいます。
この記事を読み始める前に、勝手ながら一つだけお願いがあります。もし同じ悩みを抱えているなら、この記事のコメント欄で「私も仲間です!」と点呼に応じていただけませんか?
その一言が、このニッチな領域で奮闘する(推定)数十人のエンジニアにとって、大きな励みになるはずです。
この記事は、あなたが明日から経理部門と戦う(=協力する)ための「理論武装」です。
(最後のお断りでも触れてますが、分かりやすさを優先するため、社内事情をボカして脚色・簡略化しています。)
ニッチな記事ならではのお断り
この記事では、キラキラした技術の話は一切しません。ニッチな担当者の悩みにピンポイントで刺さるような泥臭い話を展開します。
aws ce get-cost-and-usage というAPI(CLI)から吐き出されるコスト情報を現実世界の「社内費用処理」という理不尽なフォーマットに押し込み、いかにしてねじ込むか、その考え方とプロセスにのみ焦点を当てます。具体的なスクリプトコード全体は掲載しませんが、API(CLI)の利用方法に関する具体的なオプション指定例や考え方を紹介します。
なぜなら、あなたの会社の費用処理ルールは、あなたの会社にしか存在しないからです。
例えば、共有NAT Gatewayの料金1つを取ってみても、通信量で比するのか、利用部門数で頭割りするのか、はたまた各プロジェクトのEC2インスタンス数で頭割りするのか。取り決めた「按分ロジック」次第で、必要となるAPIコールやデータの扱い方が全く異なってきます。
また、月次の費用処理を迅速に行うことを主眼に置き、Cost Explorer API を利用したアプローチを紹介します。より詳細なリソース単位での分析や、大規模なデータ処理には Cost and Usage Report (CUR) を利用する方法もありますが、それはまた別次元の地獄沼の話…。まずは第一歩として、このAPIからお話します。
点呼の結果、もし多くの仲間が見つかり、例えば「CURを用いた詳細分析の泥沼」や「具体的な按分ロジックの実装例」など、さらなるニーズがあれば(あっても困りますけど(笑))別記事で地獄沼巡りをしたいと思います。
コスト配分タグは「文化」であり「規律」である
本題に入る前に、最も重要な原則を共有します。それはコスト配分タグ(Cost Allocation Tags)の徹底です。これがなければ、この先の議論は成り立ちません。「タグを付け忘れたので、インフラチームの費用でお願いします」は絶対に許してはいけません。
とはいえ、徹底出来ない部門が出るのも事実です。その場合の最終手段は、費用処理単位ごとに別アカウントを作成してもらうこと。
結果、まぁ増える増える(笑)AWSのアカウントIDが数字12桁しかないことに不安を覚えるレベルで。
弊社で徹底しているタグの例
最低限、以下のタグは全ての課金対象リソースに付与されるべき「規律」です。
-
cost-center: 経理部門が管理するコストセンターコード。請求書の宛先そのものです。 -
project: プロジェクト名やサービス名。同一コストセンター内での費用分割に利用します。 -
owner: リソースの責任者。問い合わせ先として必須です。
これらのタグは、AWS Organizationsのタグポリシー(Tag Policies)を使って必須化しましょう。「うっかり付け忘れ」を防ぎ、タグ付けを個人のスキルではなく、組織の「文化」に昇華させるのです。「No Tag, No Chargeback(タグなくして費用請求なし)」をスローガンにしましょう。
タグに指定できる値もポリシーで指定可能ですが、弊社では組織改編に合わせて頻繁にコストセンターコードの変更が発生してしまうため、マイルドに表現しても地獄です。(便利なタグエディタがあってもなお余りある面倒さ故に、別アカウント方式が増える要因でもあります)
費用按分、3つの壁
さて、タグ付けを完璧に行ったとしても、我々の前には3つの大きな壁が立ちはだかります。これこそが、費用処理担当者を夜も眠れなくさせる元凶です。
壁1 共有リソースという名の「公共料金」
複数のプロジェクトが利用する共有リソース。これらは特定のprojectタグを付けられないため、コストの迷子になりがちです。
- Direct Connect接続費用
- 共有VPC内のNAT Gateway
- 共有監視基盤(Prometheus, Grafana, Zabbix, 踏み台など)が稼働するEC2インスタンス
- その他、全社や部門で共有して利用するセキュリティサービスなど
これらの費用をどう按分するか?正解はありませんが、我々は「受益者負担の原則に基づき、合理的な基準で按分する」という方針で経理部門と合意しました。例えば、NAT Gatewayなら「各プロジェクトのVPC外へのアウトバウンド通信量比」、共有監視基盤なら「監視対象リソース数比」といった具合です。この比率を算出するのもまた、別の地獄の始まりですが…
壁2 RI/SP割引の「不公平感」
aws ce get-cost-and-usage APIでコストを取得すると、デフォルトでは UnblendedCost(非ブレンドコスト)が返ってきます。これは、リザーブドインスタンス(RI)やSavings Plans(SP)による割引が、それを購入したアカウントにのみ適用された金額です。
つまり、実際にリソースを使っているメンバーアカウントは割引の恩恵を受けられず、管理アカウントだけが安くなるという不公平な状態がデータ上発生します。これをそのまま社内請求に使うと、メンバーアカウントの利用者から「なぜうちは割引されないんだ!」とクレームが来ること間違いなしです。
そのため、弊社ではRI/SP割引共有を無効化にしています(AWSの担当者と一緒に「なんと勿体無い!」と毎月叫んでいます)。
<コラム> なぜ我々は「RI/SP割引共有の無効化」という茨の道を選んだのか?
AmortizedCost を使えば、割引額を公平に分配したコストを算出できます。これは技術的にはベストプラクティスです。
ではなぜ、弊社ではあえて「割引共有の無効化」という選択肢を取ったのか?
理由は、組織的な「納得感」と「運用のシンプルさ」を優先した結果です。
- ブラックボックス化の回避:
AmortizedCostによる割引の分配ロジックはAWSの内部処理であり、我々からはブラックボックスです。「なぜ自分のプロジェクトにこれだけ割引が適用されたのか」という問いに、明快に答え続けるための運用コストを懸念しました。 - 予算管理の安定化: RI/SPは購入タイミングや利用状況によって割引率が変動します。これを各部署の費用に反映させると、月々の請求額が予測しづらくなり、各部署の予算管理を煩雑にしてしまう可能性がありました。
- 自律的なコスト意識の醸成: 割引を全社で共有せず、各アカウント(部署)が自らRI/SPを購入・管理するルールにすることで、「自分たちのコストは自分たちで最適化する」という意識を促す狙いもありました。
もちろん、この方法には「組織全体での最適化がしにくい」という大きなデメリットがあります。(勿体無いオバケが毎月叫んでるので、もはや定番化してますが)
あなたの組織では、「中央集権的なコスト最適化」と「各部署の自律性と納得感」のどちらを重視しますか? AmortizedCost を使う方法は前者に、我々の方法は後者に軸足を置いたアプローチと言えるでしょう。ぜひ、あなたの組織に合った最適な道を探してみてください。
壁3 その他費用という名の「雑費」
AWSの請求には、リソース利用料以外にも様々な費用が含まれます。
- AWSサポートプラン費用
- APNパートナー年会費
- AWSクレジットの適用
- ルートアカウントに紐づく監査費用
- Amazon Q Developer Proのサブスク料金 ← New!!
これらは特定のアカウントやリソースに紐づかないため、コスト配分タグの対象外です。これらも「公共料金」の一種とみなし、社内ルールに基づいて分配する必要があります。
課金体系が今までとまったく異なるサブスクのAmazon Q Developerが御披露目となり、新たな経理翻訳を検討する必要が出てきました。無料のFreeティアではデータ収集がオプトアウト形式のため、弊社ではFreeティアの利用を非推奨化しようとしており、Proティアによるサブスク費用処理は避けて通れなさそうです。はぁ。。。
aws ce get-cost-and-usage との向き合い方
これら3つの壁を乗り越えるため、我々は aws ce get-cost-and-usage APIから取得したデータを加工し、社内ルールという名の魔改造を施します。大好きです、魔改造の昼(夜は業務時間外)。
生贄は、コマンドの実行そのものではなく、返ってきたJSONデータをどう解釈し、どう変換していくかです。
余談ですが、弊社の「魔改造CLI」を支える技術スタックは、なんとMicrosoft AccessのVBAからAWS CLIを呼び出し、ページネーションも処理した上でjsonを解析し、難解クエリを多段通した後、ODBC経由でバックエンドデータベースに格納しています。jqすら使わない超ストロングスタイル。もはや秘伝のタレを絵に描いたような誰にもメンテ出来ない特級呪物扱いとなっており、AWSの7Rで言うところのリファクタリングをStep FunctionsとLambdaでしたいという声も上がってます。
Step 1 「AmortizedCost」で割引の幻想を振りまく
まず、壁2で述べた割引の不公平感をなくすため、get-cost-and-usageを叩く際は、--metric に AmortizedCost を指定するのが一般的です。弊社ではコラムで説明した通り茨の UnblendedCost を指定しています。
AmortizedCost は、RI/SPの割引を、実際にそれを利用したリソースに分配した後のコストです。これにより、「AプロジェクトのEC2がSP割引の対象になった」という事実がデータに反映され、公平なコストのビューを得ることができます。これで、利用者からのクレームを一つ減らせます。
Step 2 「GroupBy」で社内請求書の明細を作る
次に、取得したデータを社内請求書のフォーマットに近づけていきます。--group-by オプションがあなたの相棒です。2段まで指定できるのは強い。
我々は通常、以下の2段階でデータを取得・集計します。
-
タグによるグルーピング:
--group-by Type=TAG,Key=cost-centerとType=TAG,Key=projectを指定し、コストセンターやプロジェクトごとの費用を算出します。これが請求書の「大項目」になります。 -
サービスによるグルーピング:
Type=DIMENSION,Key=SERVICEを指定し、サービス(Amazon EC2, Amazon S3など)ごとの費用を算出します。これが請求書の「明細」です。
この2つのデータを組み合わせることで、「A事業部BプロジェクトのEC2利用料はX円、S3利用料はY円」という、経理が求める明細を作成できます。
Step 3 タグなしリソースを狩り、「公共料金」として再分配する
get-cost-and-usage を TAG でグルーピングすると、タグが付いていないリソースのコストは、キーの値が空文字列''(Cost Explorerの画面上では (not set) と表示されることもあります)のグループとしてまとめて取得できます。これが宝の山です。
この「タグなしコスト」の中から、壁1で述べたNAT Gatewayなどの共有リソースの費用を特定します。(SERVICE や USAGE_TYPE でフィルタリングして探します、NAT Gatewayであれば USAGE_TYPE が NatGateway-Bytes となります)
特定した共有リソース費用は、全コストから一旦除外し、「公共料金プール」に移動させます。そして、事前に定めた社内ルール(例:全プロジェクトの総コスト比)に従って、各コストセンターに再分配します。
残った「本当にタグが付いていない謎のコスト」は、インフラチームのコストとして計上し、定期的に棚卸ししてゼロに近づける努力目標を立てます。
Step 4 最終調整 - クレジットとサポート費用
最後に、壁3のその他費用を按分します。
- AWSサポートプラン費用: 全社の総コストに対する各コストセンターの費用比率で按分するのが一般的でしょう。
- AWSクレジット: これも同様に、費用比率で各コストセンターに分配(マイナス計上)します。
- APNパートナー年会費: 毎月償却したこととし、費用比率で各コストセンターに按分します。
これら全ての計算を経て、ようやく「コストセンター別の最終請求額」が確定します。
まとめ。これは自動化ではなく「経理翻訳」である
お疲れ様でした。ここまで読んで、少々うんざりしたかもしれません。しかし、これこそがAWS Organizations費用処理の現場のリアルです。
aws ce get-cost-and-usage は魔法の杖ではありません。AWS世界の理(ことわり)で記述されたコストデータを、人間社会の理である「社内経理ルール」に「翻訳」するための、無骨な道具です。
この翻訳プロセスをスクリプト化することは可能ですが、本質は自動化ではなく、経理部門との度重なる交渉、アップデート対応での再交渉、社内ルールという仕様書の策定、そしてタグ付け文化の醸成といった、極めて人間的な活動の末に成り立つものです。
もし、あなたの隣に同じ苦しみを分かち合える同僚がいるならこの記事をシェアしてあげてください。Excelでの手作業から一歩でも前に進むきっかけになれば幸いです。
そして、もしあなたがこの深く暗い沼で新たな発見をしたなら発信してください。日本のどこかにいる(推定)数十人の仲間が、きっとあなたに感謝するはずです。少なくとも私は絶対感謝します。
お断り
記事内容は個人の見解であり、所属組織の立場や戦略・意見を代表するものではありません。記事化するにあたり、社内事情をボカし、分かりやすさを優先するため、内容を一部脚色・簡略化しています。
あくまでエンジニアとしての経験や考えを発信していますので、ご了承ください。