AWS BillExplained
← トピック

このコストは誰のものか

  • 時間課金されない
  • GB課金されない
  • 個数課金されない

ひとことで言うと

請求書は「何を計測したか」で並んでいる。「誰のせいか」に変換する仕組みは、先に自分で作るしかない。

なぜそうなるのか

AWS が記録するのは、常にメーター側から見た事実だ。1行の明細に書いてあるのは、どのアカウントか、どのサービスか、どの usage type か、どのリージョンか、どのレートか、そしてリソースがあればどのリソースか。どのチームか・どのプロダクトか・どの顧客かは書いていない。請求システムはそれを知らない。計測していないからだ。

「何を計測したか」を「誰が払うのか」に変換するのは別のシステムで、それを作るのは自分だ。手段は3つあり、互いに代替できない。

タグはリソースに付いたメタデータ。付けただけでは足りない。タグキーを Billing and Cost Management コンソールで有効化しないと Cost Explorer にもレポートにも出てこないし、そもそも cost allocation tags の管理画面を持っているのは組織の管理アカウント(と組織に属さない単独アカウント)だけだ。AWS は制約をはっきり書いている。タグが作られる前に作成されたリソースには、タグは適用されない。

コストカテゴリはタグの一段上にいる。コストカテゴリは全てのコスト明細行に適用されるキーと値のペアで、リソースに刻むのではなくルールで計算される。使える次元はアカウント、charge type、別のコストカテゴリ、リージョン、サービス、タグキー、usage type、billing entity。計算で決まるからタグの届かない課金にも届くし、当月の初日から有効になる: 10月15日にルールを直せば10月1日以降のコストと使用量に適用される。

アカウントは、誰も設定しなくていい唯一の手段だ。どの組織にも全メンバーアカウントの料金を支払う管理アカウントがあり、どの明細行にも最初からアカウント ID が入っている。「1チーム1アカウント」の根拠はここにある。あれはセキュリティの判断であると同時に請求の判断で、忘れることも打ち間違えることも手遅れになることもない境界は、これしかない。

AWS が計測したもの, 明細行, 誰が払うのか を通る経路。1ホップずつ:

  • AWS が計測したもの (アカウント / サービス / usage type / レート)
  • 明細行 (CUR の1行。リソース ID が空のこともある)
  • 誰が払うのか (チーム / プロダクト / 顧客)
  1. AWS が計測したもの から 明細行: ここは AWS が書いてくれる。課金されない。
  2. 明細行 から 誰が払うのか: タグ / コストカテゴリ / アカウント境界。課金されない。
どちらのホップも課金されない。問題は2本目で、先に用意しておかないとそもそも起きないし、後から起こすこともできない。 無料

で、いくらなの

按分そのものは無料だ。かかるのはリードタイムと、結局どこにも割り当てられなかった請求の取り分。

コスト配分タグには2系統ある。ユーザー定義タグは自分で付けるほうで、コスト配分レポートには user: 接頭辞で並ぶ。AWS 生成タグは予約接頭辞 aws: を使い、作成も編集も削除もできない。aws:createdBy は誰がそのリソースを作ったかを記録するタグで、有効化できるのは管理アカウントだけ、値が入るのは決められたリージョンのみ、しかも CloudTrail から組み立てられる。AWS 自身がベストエフォートだと言っていて、CloudTrail 側の問題でタグが欠けることがあると明記されている。AWS Marketplace の ISV は aws:marketplace:isv: タグをソフトウェア使用量に付けられる。Service Catalog AppRegistry のアプリケーションに紐づくリソースへ自動で付く awsApplication タグは、有効化も自動でクォータにも数えられない。請求レポート用のアクティブなタグキーの上限は500。

引っかかるのは時間差のほうだ。ユーザー定義タグを付けてから、そのキーが cost allocation tags のページに出てくるまで最大24時間。選んで有効化してから効き始めるまでさらに最大24時間。そしてそこから先の分しか集計されない。有効化は前向きにしか効かない。

戻る手段は1つだけあり、範囲は決まっている。StartCostAllocationTagBackfill は現在の有効化ステータスを過去の月に遡って適用するが、BackfillFrom は月の初日でなければならず、AWS の表現では「直近12か月より前の日付は指定できない」。リクエストは24時間に1回。何が復元されるのかを正確に読むこと。戻るのはタグキーの有効化ステータスであって、タグそのものではない。3月にタグが付いていなかったリソースは、バックフィル後も3月は未タグのままだ。

そもそもタグを付けられない課金もある。AWS はレポートに未割り当てコストが出る理由として列挙している。AWS Support や AWS Marketplace の月額のようなサブスクリプション型の課金は割り当てできない。Amazon EC2 リザーブドインスタンスの前払いのような一度きりの料金も割り当てできない。ここにタグ非対応のサービスと、期間の一部または全部でタグが付いていなかったリソースを足したものが、タグ集計と請求額の差になる。

理由は Cost and Usage Report の隣の列を見れば分かる。lineItem/ResourceId は、実体のあるホストに紐づかない usage type では空になる (AWS が挙げている例がデータ転送と API リクエストだ) し、割引・クレジット・税といった line item type でも空になる。リソースがなければ、タグを掛ける相手がいない。

内側から外側への境界:

  1. コスト配分タグ。ここを越えると: 有効化して、待つ。 リソース ID を持つ課金だけ
  2. コストカテゴリのルール。ここを越えると: 管理アカウントのみ。 当月1日から有効
  3. アカウント境界。ここを越えると: 設定不要。無料。 全明細行に最初からアカウント ID が入っている
  4. 請求書。ここを越えると: 請求の100%。 どの按分も最後はここに突き合わせる

一番内側だけが無料。リングを1枚越えて外に出るたびに関所がある。

按分の4階層を、カバー範囲の広い順に。タダなのは1つだけで、しかもそれは普通セキュリティの判断だと思われているやつ。

タグで割れないものを処理する場所がコストカテゴリだ。共有物 (NAT Gateway、基盤チームのアカウント、ペイヤー階層の固定費) をまず専用のコストカテゴリ値に分類し、その値を source、使っている各チームを target にして split charge rule を書く。配分方式は3つ。Proportional は各 target のコストで重み付け、Fixed は自分で指定した割合、Even は均等割り。source に空文字列を指定すると未分類コストを指す。1つの値を source にできるのは全ルールを通して1回だけで、split charge rule はコストカテゴリあたり10本まで。

共有クラスタには専用の答えが別にある。split cost allocation data は Amazon ECS と Amazon EKS について、タスク単位・Pod 単位の行を Cost and Usage Report に追加する。値は各コンテナが EC2 インスタンス上で消費した CPU とメモリから、インスタンスの償却後コストを基準に算出され、インスタンスの未使用分は利用率に応じて再配分される。ユーザー定義のコスト配分タグにも、namespace や workload といった Kubernetes のプリミティブにも対応している。代償は行数で、タスクまたは Pod 1つあたり毎時2行増える。

残りは一括請求が無料でやってくれる。メンバーアカウントの請求は、AWS の言い方では情報提供目的にすぎない。支払うのは管理アカウントだ。そして AWS は各メンバーアカウントに対して、その料金をアンブレンドコストで表示する。組織としての段階価格やリザベーションの恩恵は、その裏で効いたままになる。

例外と罠

必要だった四半期が終わってからタグを有効化する。 バックフィルの窓は12か月、起点は月初、リクエストは1日1回。しかも戻るのは有効化ステータスであって、付いていなかったタグではない。Q1に誰もタグを付けていなければ、コンソールを何時間いじっても Q1 の答えは出てこない。有効化はタグ規約が決まった日にやる。財務に聞かれた日ではない。

自分のリソース, Billing コンソール, Cost Explorer / CUR のやりとり。1ステップずつ:

  1. 自分のリソース から Billing コンソール: タグ付与: Team=payments。課金されない。
  2. Billing コンソール から Cost Explorer / CUR: タグキーを選んで有効化。課金されない。
  3. Cost Explorer / CUR から 自分のリソース: タグ単位で集計される。課金されない。 (応答)
  4. Billing コンソール から Cost Explorer / CUR: バックフィル要求(月初起点)。課金されない。
ここに課金は1つもない。右の欄は各ステップでレポートに何が見えるかで、要点は上の2日間、何も見えないこと。 このやり取りで回るメーターはゼロ。

リソースに付けたタグは、リソース間の通信にはタグを付けない。 NAT Gateway の後ろのインスタンスを全部タグ付けしても、Gateway の処理料金と時間料金は分割されない1行のままだ。あれは Gateway のものであって、送信側のものではないから。リソース ID が空の明細も同じ。共有インフラは split charge rule で割るまで共有のまま残る。そしてここに落とし穴がある。split charge の結果が出るのはコンソールのコストカテゴリ詳細ページだけだ。AWS はそのまま書いている。それらのコストは Cost and Usage Report にも Cost Explorer にも他のコスト管理ツールにも現れないし、影響も与えない。自前の集計パイプラインからは見えない。

似て非なるキーが、1チームを静かに2行に割る。 タグキーもタグ値も大文字小文字を区別する。Team と team と TEAM は3つの別カラムで、1チームの支出が3か所に散る。末尾の空白も同じことを、目に見えない形でやる。請求期間の途中でタグを変えたときの挙動も近い。レポートはそのリソースを変更前と変更後の2行に分割する。

未タグ=重要でない、という思い込み。 未タグの残りは、誰かが付け忘れた小物の寄せ集めではない。NAT Gateway、Transit Gateway、ロードバランサ、ログ基盤、共有クラスタ、Support の料金、リザベーションの前払い。どのチームも作っていなくて、どのチームも使っているものだ。たいていの請求書では単独で最大のブロックになる。割合を決める前に、まずコストカテゴリ値とオーナーを与えること。

出典