Community研究&データ分析github.com

mooracle/cost-attribution

AWS、Azure、Google CloudのFOCUS課金エクスポートから、組織のアカウント、タグ、クラスター、SaaSベンダーに合わせたカスタムFinOpsコスト帰属(コスト配分)システムの構築をガイドします。

cost-attribution とは?

このスキルは、AWS、Azure、Google CloudのFOCUS課金エクスポートを基に、組織固有のアカウント、タグ、クラスター、SaaSベンダーに合わせたカスタムFinOpsコスト帰属(コスト配分)システムを構築するための包括的なガイドです。ユーザーの実際の請求データを最初にスキャンし、データから得られない情報のみをインタビューで収集し、検証済みプロファイルに記録します。コンポーネントごとに「READY/BLOCKED/NOT_A_FIT」の判定を下し、仕様とゴールデンテストケースに基づいてフェーズごとに構築を進め、各フェーズ後に検証ゲートを実施します。このスキルは、チーム、アプリ、コストセンター別のチャージバックやショウバック、商用FinOpsツールの代替、FOCUSエクスポートの活用、エンタープライズサポートなどの共有コストの分割、KubernetesネームスペースやSaaSベンダー請求書の帰属に最適です。Claude Code、Cursor、CodexなどのAIエージェントプラットフォームで利用できます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mooracle/finops-skills/tree/HEAD/skills/cost-attribution

Installed? Explore more 研究&データ分析 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

組織に合わせたコスト帰属の構築

あなたは一人のユーザー(そして、組織にファイナンス担当者がいる場合はそのパートナー)をガイドしながら、標準スキーマ(FOCUS)とサーバーレスランタイムの間を繋ぐ、主にグルーコードで構成される構築を行います。パターンは固定されていますが、形状はユーザーの組織に合わせます。あなたの仕事は、ユーザーのデータからその形状を見つけ出し、それを文書化し、パターンを適用することです。汎用的な製品をインストールすることは決してありません。

各パターンがなぜ適切なのかを説明した記事があります: https://mooracle.io/blog/build-custom-finops-tool/(パート1~7)。ユーザーが「なぜ」と尋ねたら、該当するパートを示し、セッションは「どのように」に集中させてください。

不変条件

これらはプロファイルによって変化しません。生成したコードをユーザーに表示する前に、これらに照らしてチェックしてください。

  1. すべての分割は合計を維持する。 コスト列ごとに SUM(out) == SUM(in) です。分割ツールは金額を移動させますが、作成も破棄もしません。
  2. クエリ時に割り当てる。 組織カテゴリはビュー内で、ルックアップを通じてアタッチされます。ウェアハウスの行に team を書き込まないでください。
  3. チャージバックには EffectiveCost を使用する。 BilledCost は請求書と照合し、ListCost は節約額を測定します。これらを混在させないでください。
  4. 月全体を再構築する。 各 (billing_period, provider) パーティションは、配信のたびに生データからクリアおよび再書き込みされます。デルタやマージはありません。
  5. 昨日までのデータに制限する。 本日以降のデータはウェアハウスに取り込まれません。
  6. 各分割は1回のファンアウトである。 分割する行は、通常のロード内で重みを結合し、重みごとに1行になります。キーの重みの合計は1.0になります。均等配分、Kubernetes、ベンダー分割はすべて、1つの split_weights テーブルを通じてこの方法で機能します。ロードから除外されて後から追加されるものはありません。そのため、除外を忘れることがなく、何も二重にカウントされません。
  7. 毎回の実行は数値を証明する。 Rawテーブルは、プロバイダーのマニフェストがリストするファイルを正確に保持し、ブロッキング合計チェックが請求書を両方のベーステーブルと比較し、不一致があった場合は実行を失敗させ(書き込んだものをクリアします)。ビューが存在すると、すべての実行およびクローズ時に、services_monthly が base_monthly を正確に提供するかどうかもチェックします(ビューチェックは失敗してもクリアしません)。
  8. コストを決して失わない。ルーティングは失敗する可能性がある。 分割を安全に実行できない場合、コストは請求された状態でそのまま保持されます。スキップされた分割は可視化されますが、失われたコストは見えません。
  9. Raw読み取りは正確な月単位。 WHERE billing_period = 'YYYY-MM' を使用し、エンジンのスキャン上限を有効にします(Athenaではワークグループのバイト上限)。全履歴の読み取りは base_monthly(メガバイト単位)に対してのみ許可されます。
  10. 共有列は一度、ビュー内で分類する。 x_namespace はKubernetesとSaaSのワークスペースの両方を保持し、split_by がどちらかを示します。値の形状から推測しないでください。

ユーザーのリポジトリに保持するファイル

フェーズ0で finops/ を作成するか、ユーザーが希望する場所に作成してください。そのパスを最初の D-001 として記録します。以下では、finops/ はそのパスを意味します。

  • finops/profile.yaml — 組織の形状。assets/profile.template.yaml から開始します。すべてのフェーズがこれを読みます。これ以外に組織固有の決定を保持するものはありません。

  • finops/DECISIONS.md — 追記専用のログ。エントリを編集しないでください。新しいエントリで置き換えてください。

    ## D-007 Enterprise Support は共有 (2026-10-17)
    ソース: 2026-09 の D5; Q-S1 に <user> が回答
    決定: 同一月のファーストパーティ支出に基づき、支払者ごとに分割
    置き換え: —
    

    発見結果、回答、前提、承認、および 否定的な決定(「日次重みテーブルを試したが、月内で構成が変動しないためロールバック。再提案しない」)はすべてここに記録されます。プロファイルの evidence フィールドはこれらのIDを指します。

  • finops/STATUS.md — フェーズごとに1行:状態、数値付きゲート結果、ゲートが通過したコミットSHA、およびフェーズが依存するプロファイルフィールド。

    | Phase | State | Gate | At | Depends on |
    | 3 base tables | passed | 2026-09 bill 120,000.00 = monthly 120,000.00 | a1b2c3d | providers, dimensions, routing.key, finance, period_charges, shared_costs |
    

実行ループ

開始時

  • finops/STATUS.md が存在する → 再開: STATUS、DECISIONS、プロファイルを読み込みます。通過した各フェーズについて、git diff <そのSHA> -- finops/profile.yaml を実行します。依存するフィールドが変更されている場合、そのフェーズ およびその出力を読み取る後続のすべてのフェーズ(1 → 2 → 3; 3 → 4, A, B, 5; 4 → 5)を再開します。最後に通過したゲートを現在のデータに対して再実行します(データも変動します)。最初の未通過フェーズから続行します。
  • ユーザーが変更(再編成、新しいアカウントファミリー、新しいベンダー、新しいクラスター)を報告した場合 → 更新: 対応する発見クエリを再実行し、プロファイルと差分を取り、変更があった部分のみを再度質問し、再チェックし、依存するフェーズを再開します。
  • ユーザーが最初に動作を確認したい、またはまだ課金アクセスを許可したくない場合 → トライアル(references/trial.md):DuckDB上での合成月、認証情報不要、解答キーと照合。実際のビルドには何も引き継がれません。
  • それ以外の場合 → 以下の 開始 に進みます。

1. 質問する前に発見する

references/discovery.md を読み、そのクエリを、最後に確定した月に対して、すでにエクスポートが配置されている場所(そのファイル上のテーブル、またはエンジンがない場合はダウンロードされた配信に対するDuckDB)で実行します。これらのクエリは、ビルドが存在する前に実行します。すべての結果を表示します。それぞれを D-NNN として記録します。発見は読み取りのみで、アカウント内の何も(タグのアクティベーションでさえも)変更しません。

エクスポートがない場合 → ブートストラップパス: エクスポートを有効にし(references/focus-export.md)、データを伴わないインタビューラウンド(組織、ランタイム、カテゴリ、ファイナンス)を実行し、期待されるレイアウトに対してスタックを構築し、最初の配信が届いた次のセッションで発見を実行します。待機中はトライアル(references/trial.md)を提供します。

2. ギャップを埋めるためのインタビュー

references/intake.md を読みます。停止または想定のルール:

  • 回答が 金額または所有権 に影響する場合 → null のままにします。コンポーネントは BLOCKED のままです。
  • 名前、場所、またはツール の場合 → デフォルトを使用し、assumptions: エントリと D-NNN を追加して先に進みます。

もっともらしい推測、フィクスチャ、または例の値で事実を埋めないでください。

3. 計画をチェックし同意する

references/plan.md が説明するチェッカーを finops/ に書き込み(ルールごとに1つのテストで、一度だけ)、プロファイル上で実行します。コンポーネントごとに1つの判定と、何がビルド可能か(依存関係のすべてがREADY)を出力します。それを表示します。 各 BLOCKED 行について、回答できる人と正確なプローブを指名します。各 NOT_A_FIT について、より単純な代替案を口に出して言います。これには、組織の方針がそう指示する場合の「これをビルドしない」も含まれます。計画の明示的な承認を得ます。それを D-NNN として記録します。

4. フェーズごとにビルドする

以下のマップの各フェーズについて、順番に(オプションのトラックAとBはフェーズ4の後、READYの場合のみ):

  1. エントリチェック。 --entering <phase> を付けたチェッカーが終了コード0で終了し、依存するすべてのフェーズがSTATUS.mdでpassedになっていること。
  2. スペックを読む(references/<file>、フェーズマップのSpec列):契約、不変条件、および即興で対応すると問題が発生するエッジケース。
  3. ユーザーのスタックで記述する。 フェーズのコンポーネントをユーザーのエンジンと言語(Athena、BigQuery、Snowflake、Databricks、dbtなど)で、ユーザーのリポジトリのスタイルで、プロファイルによって形作られるように構築します。providers.md からのプロバイダーごとのアダプタ、プロファイルが必要とする分割のみ、ルーティングする列のみ。スペックは何が成立しなければならないかを、ケースは何が出力されなければならないかを示します。コードはあなたが書くものです。エラーが黙認される箇所(重み、日次への展開、合計チェック、通貨ガード)には最も注意を払ってください。
  4. ゴールデンケースを移植する(cases/*.yaml; 方法は references/testing.md にあり)、このフェーズが構築したものに適用されるケースを移植し、組織固有の適応ごとにケースを追加します。ケースがパスするまでフェーズは構築されたと見なされません。
  5. デプロイしてゲートを実行する 実際のデータに対して。ゲートは、正常な場合に0行を返すSQLです。数値を表示します。
  6. 結果、SHA、および依存関係をSTATUS.mdに記録する。

毎回のゲートレポート:

Gate 3 (base tables), 2026-09, aws: PASSED
  bill 120,000.00 · monthly 120,000.00 · daily 120,000.00 · drift 0.00
  support: 1 row → 12 accounts, weights sum 1.000000

ゲートの失敗はビルドを停止します。スペックの障害テーブル(各チェックの問題名は reconciliation-ops.md の「Failure modes」にあります)でデバッグし、修正し、再実行します。

フェーズマップ

PhaseBuildsProfile fieldsSpecCasesGate
0発見、インタビュー、チェッカー、計画alldiscovery.md, intake.md, plan.md—計画承認済み (D-NNN)
1FOCUSエクスポートprovidersfocus-export.md—フル月がクエリ可能 (D0)
2ストレージレイアウト、エンジン、テーブル、およびrawを満たす配信(コピーまたはポーラー、ステージング、ETLの公開ステップ)runtime, providersstack.md, data-model.md, pipeline.md (「Delivery」)—公開された月がそのマニフェストと一致する; raw月のクエリがその月のファイルの一部のみをスキャンする
3アダプタ、按分と共有コスト分割を含むベーステーブル、ETLの再構築providers, dimensions, routing.key, finance, period_charges, shared_costsproviders.md, data-model.md, splitters.md, pipeline.mdadapters, load, share, checks確定月において、支払者ごとに bill == monthly == daily
4ルール、ルックアップ、ビューcategories, routingrules-engine.mdrules, viewsカテゴリが表示される; Unallocatedがレポートされる
ASaaS分割saas.vendorssaas.mdvendorベンダーが split を表示; 合計が保持される
BKubernetesネームスペースkuberneteskubernetes.mdk8s重みがクリーン; カバレッジ ≥ 目標
5調整、運用、クローズfinance, org.finance_partnerreconciliation-ops.md, testing.mdchecks組織が請求書合計を入力する場合 (Q-F5)、確定月がすべてのプロバイダーに対して請求書チェックに合格し、その結果が月とともに保存される; 意図的に破損した分割が開発コピーで実行を失敗させる; ファイナンスパートナー(いない場合は所有者)との数値のウォークスルー

references/pipeline.md には、これらのコンポーネントがランタイムに実行される処理順序が記載されています。

自由度

  • 固定(エンジンに関係なく):不変条件、およびケースが出力しなければならないと言っているもの(adapters.yaml は例外:これはエクスポートの生の形状に対する1つのプロファイルの選択を示しています):按分ルール、合計が1.0になる重みによるファンアウト、プロデューサーのゲート(支払者ごと、正の支出、月全体のベンダーデータ)、チェックとその停止条件、実行順序と障害時のクリア、未入力のクエリパラメータの拒否。
  • ユーザーが自由に決められる(ユーザーのコードベースに合わせて自由に記述):エンジンと言語、ファイルレイアウト、Infrastructure as Code、パッケージング、スケジューリング、ダッシュボード、CI、およびファイル、関数、インフラストラクチャの名前(ただし、ケースが使用するテーブル、列、問題名は固定)。

変更がどちらの側にあるか不明な場合は、固定側と見なします。

ユーザーが反対した場合

references/pushback.md に、よくある反対意見(「ETLで割り当てる」「100%マッピングする」「すべてのベンダーに1つのフレームワーク」「ポッド単位の精度」)とその回答、および記事で議論されている箇所が記載されています。

完了条件

  • 確定したすべての月が、すべてのプロバイダー、すべての分割を通じて合計チェックに合格し、組織が請求書合計を入力する場合は請求書チェックにも合格していること。
  • コストを報告する人(ファイナンスパートナー、いない場合は所有者)が、新しいSQLなしでビューから「先月のチームXのコストはいくらだったか?」に答えられること。
  • ルールの変更はプルリクエストであること:CIが展開され、レビュアーは何が変わるかを確認し、マージは履歴全体を再構築せずに再分類する。
  • Unallocated が金額、通貨単位でアラートされ、減少傾向にあること。
  • 実行コストが小さく、測定可能であること(リファレンススタックでは、月間1500万請求ラインの場合、S3、Athena、Lambdaを合わせて月額約10ドル。Athenaのシェアはワークグループのスキャンメトリクスに含まれる)。
  • STATUS.md に、計画がビルドするすべてのフェーズがSHAとともにpassedと表示されていること。DECISIONS.md は、新参者が疑問に思うであろうすべての選択を説明していること。

関連スキル