共同利用方式で Savings Plans の割引が適用される額がコスト配分タグごとに確認できるのか検証してみた

ガバメントクラウドの AWS で、共同利用方式のうちネットワーク分離またはアプリケーション分離の方式を採用する場合、共同利用する各団体の請求額を按分するには、コスト配分タグを使うことが想定されます。

ガバメントクラウドの費用按分に関する公開ドキュメントはほぼないようですが、AWS が「ガバメントクラウド活用のヒント『共同利用方式におけるコスト・セキュリティ管理について』」という記事を書いており、恐らくこういった方法になると考えられます。

> 費用按分の方法の考え方の一例として「リソースの Owner が明確なものはコスト配分タグで費用を按分し、タグ付け不可の場合・複数の団体で同じリソースを共用する場合は利用量・団体の人口規模等の指標で按分する」という考え方があります。
> 
> ここでは、上記の方法で費用按分を実施する方法の概要について説明します。

https://aws.amazon.com/jp/blogs/news/govcloud-hint-for-shared-use-cost-security/

また、公開されている GCAS ガイドに、ガバメントクラウドで利用可能なコスト配分タグが記載されています（ガバメントクラウドの費用按分について触れている唯一の公式ドキュメントかと思います）。

https://guide.gcas.cloud.go.jp/aws/cost-optimization/#%E3%82%AC%E3%83%90%E3%83%A1%E3%83%B3%E3%83%88%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%B3%E3%82%B9%E3%83%88%E7%AE%A1%E7%90%86%E9%81%8B%E7%94%A8

## アカウント分離以外の共同利用方式では利用団体で割引の意識合わせが必要では？

ここで、共同利用方式でリザーブドインスタンスや Savings Plans の購入を考えたとき、ふと疑問が浮かびました。

それは、ネットワーク分離またはアプリケーション分離の共同利用方式により一つの AWS アカウントで複数の利用団体のリソースを運用している環境で、リザーブドインスタンスや Savings Plans といった割引を購入する時、割引もちゃんと利用団体の希望通りに按分されるのでしょうか？

というのは、AWS アカウントが同一の場合、これらの割引は条件に合致するものから適用されるため、アカウント内のこのリソースに適用させたいというコントロールはできません。

例を挙げてみます。A と B の二つの団体がネットワーク分離の共同利用方式で運用しており、EC2 を次のとおり運用しているとします。

| 団体 | EC2 インスタンス  |
|:----:|:-----------------|
| A    | m6i.xlarge 1 台  |
| B    | m6i.2xlarge 1 台 |

A 団体の希望で m6i のインスタンス Savings Plans を m6i.xlarge 1 台分の利用額をコミットすることにしました。

しかしこの場合、同一アカウント内の B 団体の EC2 インスタンスの方が、インスタンスサイズが大きく利用料金は高く、かつコミットした Savings Plans の割引の条件に合致してしまっているため、B 団体の EC2 インスタンスに割引が適用されてしまいます。

費用按分の方法が、シンプルに総額を何らかの基準で分けるだけならば問題ありませんが、EC2 インスタンスにコスト配分タグを付けて厳密な費用按分をしようとしたら、A 団体は期待した割引が受けられないことになります。

リザーブドインスタンスも同様に、同一アカウント内に条件を満たす EC2 や RDS のインスタンスがある時に似たようなことが起きますし、共同利用する団体同士で割引の方針をすり合わせしたとしても、他団体の都合で希望どおりの割引が使えない状況は避けられないと思われます。

## そもそもコスト配分タグで割引がいくら適用されたのかを確認できるのか？

これはネットワーク分離・アプリケーション分離の共同利用方式の仕組みの問題なので、課題は一旦置いておくとして、そもそもコスト配分タグごとに、割引がいくら適用されたか把握することは可能なのか気になりました。

そこで、先日検証で購入した Savings Plans を使って、コスト配分タグごとに Savings Plans がいくら適用されたか、Billing and Cost Management のデータエクスポートを使って請求内訳から確認できるか調べてみました。

せっかくなので、Savings Plans を適用している間、他に優先して条件が合う EC2 インスタンスを立てた場合、そちらの EC2 インスタンスに割引が適用されることも併せて検証してみます。

## 検証のシナリオ

先日、以下の記事で t4g.nano の EC2 インスタンス 1 台分の Compute Savings Plans を購入したアカウントがあります。1 年間前払いなし、東京リージョンの共有テナンシーの Linux なので、コミット額は 0.0042 USD となっています。

https://qiita.com/takeda_h/items/1e82b477951ac453c10f

このアカウントで、今起動している t4g.nano の EC2 インスタンスに加えて、t2.micro の EC2 インスタンスを追加で起動します。t2.micro の方が t4g.nano より利用料が高いため、t2.micro を起動したときから Savings Plans は t2.micro のインスタンスに適用されてしまう想定です。

t2.micro の EC2 インスタンスの方にコスト配分タグを付け、このコスト配分タグでデータエクスポートの請求データをフィルタしたときに、Savings Plans がいくら適用されたか確認できるか試してみます。

## コスト配分タグの有効化

適当に t2.micro のインスタンスを起動し、コスト配分タグを追加します。タグキーは適当に、値は「testtag02」としました。

![スクリーンショット 2025-03-15 143222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443658/0b3e85ec-a620-45b6-93f2-0ecad8e25fa0.png)

このアカウントがメンバーアカウントとなっている Organizations の管理アカウントでコスト配分タグを有効化します。これでデータエクスポートの請求内訳にコスト配分タグごとの内訳が出力されるようになります。

![スクリーンショット 2025-03-15 143542.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443658/1810e2b1-f537-4f3f-8ec4-8d74cd21253f.png)

:::note
検証に当たって一つ失敗していて、コスト配分タグは有効化してから請求内訳に反映されるまでに結構時間がかかります。そのため検証の請求内訳データが分かりづらい構造になってしまいました。本番でコスト配分タグを使う場合は、請求期間の開始前に余裕をもってコスト配分タグを設定する必要があります。
:::

## Billing and Cost Management からデータエクスポートを実行

データエクスポートの手順は次の記事で解説しています。S3 バケットに CSV で請求内訳データを出力するようにしています。

https://qiita.com/takeda_h/items/84c5d37e18c5659c19e2

S3 バケットから請求内訳をダウンロードして Excel で開いて確認してみます。

![スクリーンショット 2025-03-15 190436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443658/1aeef02a-a41e-4954-9390-a3b6c09244ec.png)

月の途中でコスト配分タグを設定してしまったため、分かりづらいデータになってしまっていますが、ここから Savings Plans の割引がいくら適用されたか確認してみます。

「resource_tags」列が「{"user_cost_tag":"testtag02"}」となっている行のデータが今回コスト配分タグを設定した部分のものになりますので、この行のデータに着目します。

まずは Savings Plans が適用された時間数が確認できるか見てみます。

「line_item_usage_amount」列が EC2 インスタンスを起動している時間となります。ここで、Savings Plans のコミット額は 0.0042 USD ですが、同じ条件で計算した t2.micro の Savings Plans 料金は 0.0118 USD です。そのため、この EC2 インスタンスは、実際に起動している時間に、0.0042/0.0118 を乗じた時間だけ Savings Plans の割引が適用され、残りの時間はオンデマンド料金となるはずです。

それでは「line_item_line_item_type」列が「SavingsPlanCoveredUsage」となっている行の「line_item_usage_amount」列の値を見てみます。データ出力時点で t2.micro の EC2 インスタンスの起動時間は 18 時間だったのですが、「line_item_usage_amount」の値は 18 * 0.0042/0.0118 = 6.40678 時間となっていました。

これにより、想定したとおり、Savings Plans は元々起動していた t4g.nano の EC2 インスタンスではなく、追加で起動した t2.micro の EC2 インスタンスに適用され始めたことが確認できました。

次に Savings Plans が適用された利用金額を確認します。

想定では 0.0118 USD * 6.40678 時間 = 0.0756 USD となるはずです。ここで、「savings_plan_savings_plan_effective_cost」列のデータを見ると、0.0756 となっています。この列の意味は次のとおりなので、これが Savings Plans が適用された利用金額と考えてよさそうです。

> 各使用量の行に割り当てられている Savings Plan 月額料金 (前払いおよび定額) の比率。

https://docs.aws.amazon.com/ja_jp/cur/latest/userguide/table-dictionary-cur2-savings-plan.html

以上のことから、少なくとも Savings Plans については、コスト配分タグごとにいくら適用されたかは把握することは可能であることが分かりました。

## まとめ

- Savings Plans は、他に優先して適用すべきリソースがある場合はそちらに割引が適用されます
- コスト配分タグごとに、Savings Plans がいくら適用されたかは確認可能です

一応、ネットワーク分離・アプリケーション分離の共同利用方式でコスト配分タグを使って費用を按分する場合に、Savings Plans の適用額は確認できるため、説明はできそうです。

ただし、リザーブドインスタンス・Savings Plans の適用リソースをコントロールできない点は致命的で、運用としてこれでは使えないのではないでしょうか。

また、この仕組みを理解して相手に説明したり、請求額を見て検査したりすることは正直厳しくないですかこれ……と思いました。