ガバメントクラウドの AWS メンバーアカウントで請求書の内訳（利用実績）を確認するにはどうしたらいいのか（CUR 2.0）

ガバメントクラウドの利用料を地方自治体が支払うにあたって、契約の履行状況の検査として各自治体は請求期間の課金対象リソースの利用実績（使用数量）を把握する必要があるが、ガバメントクラウドのスキームの中でこれが極めて難しいのでは？と問題提起がありました。

https://note.com/techniczna/n/n7cef89c33de8?sub_rt=share_pw

問題のきっかけとなるのは以下の箇所です。

> 地方自治法第２３４条の２第１項において、地方公共団体は政令の定めるところにより契約の適正履行の確認のための検査を行わなければならないとあり、該当の政令である地方自治法施行令第１６７条の１５第２項には契約書（中略）その他の関係書類に基づいて行わなければならないとあります。
> 
> 即ち当該契約は単価契約ですので、為替レートはのことはさておき、単価×実績に基づいた数量＝請求額になっていることを確認せねばならないということです。

高橋さんの Note 記事で上記に起因する諸問題と解決方法について詳しく書かれていますので、ガバメントクラウド利用料の支払いに関係する方達は必見です。

ここで私は、じゃあガバメントクラウドの AWS、つまり Organizations のメンバーアカウントで、請求期間の課金対象リソースの使用量を把握するには、どういった方法が考えられるかについて試してみました。

## Billing And Cost Management を確認する

### 請求書から確認する

まずは普通に第一選択肢は Billing And Cost Management で請求書を確認することです。

請求書には EC2 や Route 53 など、利用したサービスの課金対象リソースごとに、単価と利用実績（EC2 の稼働時間や Route 53 ホストゾーンを使用した数など）が表示されています。また、エンタープライズ割引や Savings Plans の割引が適用された金額も請求書から確認することができます。

Billing And Cost Management の請求書は PDF だけではなく CSV でエクスポートする機能もあります。しかし、ガバメントクラウドでは Organizations のメンバーアカウントとなるため、請求書を CSV で出力することができません。これでは機械的に処理することがしんどいので、他に方法はないか考えてみます。

### データエクスポート（CUR 2.0）で請求書データを出力する

Billing And Cost Management では請求データをプログラマブルに処理しやすい形式でエクスポートするデータエクスポート（CUR 2.0）という機能があります。具体的には Parquet 形式か CSV 形式でテキストファイルの請求データを S3 バケットに吐き出すことができます。

https://dev.classmethod.jp/articles/data-export/

cur と bcm-data-exports の API アクセスを SCP で許可されていればですが、データエクスポートであれば CSV などの機械的な処理をしやすい形でデータを入手できます。また、SQL で検索条件を設定できるので、例えばコスト配分タグごとにデータエクスポートを作成し、別の S3 バケットにデータを出力するといったことが可能です。

データエクスポートをうまく使って課金対象のリソースの利用実績を確認するのが一番楽ではないでしょうか。

しかし、この問題はそう簡単ではありません。

## 共同利用方式では地方自治体側で Billing And Cost Management が使えない

高橋さんの Note 記事のとおり、ガバメントクラウドのスキームにおいては、単独利用方式（アカウント所有者が地方自治体）であれば職員が自らマネージメントコンソールにアクセスし、Billing And Cost Management を使用できますが、共同利用方式（アカウント所有者が事業者）の場合はこれができません。

そのため、共同利用方式の運用管理補助者の事業者に対し、自団体分の利用実績の分かるデータエクスポートの作成を依頼するしかないと思います。

しかし、データエクスポートを作成するにも SQL のメンテナンスや S3 バケットの管理など新たな工数が発生しますし、運用管理補助者の委託業務の仕様の範囲にこの作業が含まれてない場合、事業者側としても無償では行うことは難しいと思われます。

また、Billing And Cost Management はアカウントごとの操作となるため、事業者側としても、アカウントが多くなってくるとデータエクスポートして請求データを各地方自治体へ配布するまでの一連の工程も手作業とはいかなくなるので、AWS CLI や CDK などで開発が必要となり、運用工数が増えてしまいます。

これを 1741 ある全ての地方自治体やそれを運用管理補助する事業者で行うのはモダンではありません。

そこで、デジタル庁に対し、提案したいことがあります。

それは、 **Organizations のマスターアカウントでのみ可能な、全アカウント別のデータエクスポートを作成し、各地方自治体へ配布してもらえないでしょうか？** ということです。

具体的な例として、データエクスポートの SQL で対象のアカウントのみ抽出するデータエクスポートを作成し、毎月データエクスポートからアカウントごとに別の S3 バケットに請求データが出力するソリューションを考えてみました。これにより、地方自治体や運用管理補助者はこれを取りに行く運用が可能になると思います。

それではこのソリューションの具体的な手順を試してみます。

## データエクスポートの作成（AWS CLI）

### SQL クエリの作成

Billing And Cost Management のマネージメントコンソールからでは、データエクスポートで出力する列の指定はできますが、特定のアカウントのみといった WHERE 条件は指定できず、指定するためには AWS CLI/CDK でデータエクスポートを作成/編集する必要があります。

公式ドキュメントの bcm-data-export API のリファレンスを読むと、--export 引数に指定する構造体の QueryStatement プロパティに SQL クエリを指定することで、マネージメントコンソールでは指定できない SQL クエリを設定できることが分かります。

https://docs.aws.amazon.com/ja_jp/cli/latest/reference/bcm-data-exports/update-export.html

構造体は JSON で書けるので、SQL クエリに指定できる内容を公式ドキュメントで確認しながら、次のとおり JSON を作成しました。WHERE 句に line_item_usage_account_id = '対象の AWS メンバーアカウント ID' と条件を与えています（出力先の S3 バケットは東京リージョンとしました）。

WHERE 句が使えるので、例えば特定のコスト配分タグのみを抽出といったことも可能かと思います。

https://docs.aws.amazon.com/ja_jp/cur/latest/userguide/dataexports-data-query.html

```json
{
    "DataQuery": {
        "QueryStatement": "SELECT bill_bill_type, bill_billing_entity, bill_billing_period_end_date, bill_billing_period_start_date, bill_invoice_id, ...（列指定、省略）...
        FROM COST_AND_USAGE_REPORT WHERE line_item_usage_account_id = '対象の AWS メンバーアカウント ID'",
        "TableConfigurations": {
            "COST_AND_USAGE_REPORT": {
                "INCLUDE_MANUAL_DISCOUNT_COMPATIBILITY": "FALSE",
                "INCLUDE_RESOURCES": "TRUE",
                "INCLUDE_SPLIT_COST_ALLOCATION_DATA": "TRUE",
                "TIME_GRANULARITY": "MONTHLY"
            }
        }
    },
    "Description": "BCM Test",
    "DestinationConfigurations": {
        "S3Destination": {
            "S3Bucket": "請求データの出力先とするバケット",
            "S3OutputConfigurations": {
                "Compression": "GZIP",
                "Format": "TEXT_OR_CSV",
                "OutputType": "CUSTOM",
                "Overwrite": "OVERWRITE_REPORT"
            },
            "S3Prefix": "CUR",
            "S3Region": "ap-northeast-1"
        }
    },
    "Name": "データエクスポート名",
    "RefreshCadence": {
        "Frequency": "SYNCHRONOUS"
    }
}
```

### 出力先の S3 バケットの作成

マネージメントコンソールからデータエクスポートを作成する場合は一緒にデータ出力先となる S3 バケットも作成できるのですが、AWS CLI からではできなかったので、別途 S3 バケットを作成します。

データエクスポート以外からバケットにデータを書き込めないよう、公式ドキュメントを参考に以下のとおりバケットポリシーを設定します。

https://docs.aws.amazon.com/ja_jp/cur/latest/userguide/dataexports-s3-bucket.html

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EnableAWSDataExportsToWriteToS3AndCheckPolicy",
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "billingreports.amazonaws.com",
                    "bcm-data-exports.amazonaws.com"
                ]
            },
            "Action": [
                "s3:PutObject",
                "s3:GetBucketPolicy"
            ],
            "Resource": [
                "arn:aws:s3:::${bucket_name}/*",
                "arn:aws:s3:::${bucket_name}"
            ],
            "Condition": {
                "StringLike": {
                    "aws:SourceAccount": "${accountId}",
                    "aws:SourceArn": [
                        "arn:aws:cur:us-east-1:${accountId}:definition/*",
                        "arn:aws:bcm-data-exports:us-east-1:${accountId}:export/*"
                    ]
                }
            }
        }
    ]
}
```

### AWS CLI からデータエクスポートをデプロイ

JSON と S3 バケットが作成できたら、AWS CLI からコマンドでデータエクスポートをデプロイします。

```console
$ aws bcm-data-exports create-export --export=file://先ほど作成した.json --region ap-northeast-1 --profile 適切なクレデンシャルのプロファイルを指定
```

成功すると JSON で ARN が返ってきます。しばらく待つと、指定した S3 バケットに gzip で圧縮された CSV ファイルが作成されます。

![スクリーンショット 2025-03-08 201421.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443658/4723536f-1084-4bdd-8637-3c4f1f30b8b6.png)

あとは Excel なりでよしなに利用実績が確認できるようになっていますので、Excel で開いてみます。

![スクリーンショット 2025-03-08 202330.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443658/80531fba-a616-45b6-bfe1-85f2d3b7afd7.png)

少し分かりづらいですが、どのリソースを何の単位でどれくらい使用したのかが分かるようになっています。

## 請求時のドル円レートを確認する方法はあるのか？

### 請求時のドル円レートについていつ時点かは明らかにされていない

ところでデータエクスポートで出力したデータは、全て US ドルとなっています。AWS の支払い通貨を日本円に設定している場合、請求時点のドル円レートで円に換算されて請求されますが、このドル円レートはどう確認すればいいでしょうか？

残念ながらデータエクスポートで出力するデータの中にはドル円レートは持っていませんでした。AWS 公式はどう説明しているか見てみます。

> Q. 米ドルの請求金額を希望支払い通貨に変更する場合は、いつの為替レートが使用されますか？
> 請求書が発行されるタイミングで適用されるレートが決定しますが、そのレートの算出方法や参照元に関しましてはこちらのドキュメント(英語版)にてご確認いただける内容以上の情報は公開されておりません。
> 実際に適用されたレートは、発行された PDF 請求書上にてご確認ください。

https://aws.amazon.com/jp/aws-jp-faq/

> When using a non-USD currency, consider the following:
> All preferred currency amounts shown in the AWS Billing and Cost Management console are estimated in USD.
> Your finalized monthly bill is generated in the local currency that you choose.
> Rates can change daily. The exchange rate applied to your invoice is determined when your invoice is created.
> Note: Currency conversion is provided by Amazon Services LLC.

:::note
（筆者訳）
最終的な毎月の請求は、選択した通貨で作成される。
レートは請求書が作成される時に決定される。
通貨の換算は Amazon により提供される。
:::

https://repost.aws/knowledge-center/non-us-currency

要するに、具体的にどの時点のドル円レートなのかは公式には明らかにされていないようで、「発行された PDF 請求書上にてご確認ください」ということのようです。

### PDF 請求書でしか請求時のドル円レートは分からない

この「発行された PDF 請求書」とは、AWS アカウントの請求書の送付先に設定しているメールアドレスに毎月送付されるものです。以下のスクショは 2025 年 2 月分の請求書のもので、1 ドル = 153.04926425 円となっていることが分かります。

![スクリーンショット 2025-03-19 135644.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443658/febb0567-f0b9-48c3-82c4-b72c07f53af8.png)

現状、この PDF 請求書をもってしか請求時のドル円レートを把握する方法はないようです。

### Organizations 環境ではメンバーアカウントで PDF 請求書を受け取れない可能性がある

ここで、ガバメントクラウドにおいては、デジタル庁が地方自治体から集めて CSP へ支払うスキームです。

> デジタル庁は、地方公共団体が利用するクラウドサービスをまとめて提供するため、CSP と「ガバメントクラウド提供契約」を締結する。
> 具体的には、次の内容の契約を締結する。
> - デジタル庁は、CSP に対し、クラウドサービス利用の対価として地方公共団体から受領したクラウドサービス利用料相当額を支払う。

[地方公共団体情報システムのガバメントクラウドの利用について【第 2.1 版】](https://www.digital.go.jp/assets/contents/node/basic_page/field_ref_resources/c58162cb-92e5-4a43-9ad5-095b7c45100c/a3f24ea9/20240705_policies_local_governments_outline_04.pdf) 

また、ガバメントクラウドの AWS 環境で地方自治体は Organizations のメンバーアカウントであることから、Organizations の「一括請求（コンソリデーティッドビリング）」を使っていることは間違いないと思います。

https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/consolidated-billing.html

では Organizations で一括請求（コンソリデーティッドビリング）を有効にしている場合、メンバーアカウントで毎月の PDF 請求書を受け取れるでしょうか？

答えは、恐らくできないのではないかと思われます。Organizations で一括請求（コンソリデーティッドビリング）を有効にした状態で、メンバーアカウントから請求書の送信設定を行えるかマネージメントコンソールを見てみたのですが、設定自体ができないようで、また、支払アカウントでもメンバーアカウントに個別で請求書を送信するような設定が見当たりませんでした。

![スクリーンショット 2025-03-22 203300.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443658/85a2c77e-40a0-4ae2-aafb-39e8eddaf51b.png)

結論としては、ガバメントクラウドにおいては地方自治体が請求時のドル円レートを自力で把握することはできず、デジタル庁から情報提供してもらうしか知る術はないのではないかと思われます。

## Organizations の機能的に請求データ管理はマスターアカウントで設定すべき

いかがでしょうか？マスターアカウントでは特に SQL で指定しなければ全アカウントの請求データを一括でデータエクスポートできますし、挙げた例のように SQL クエリでアカウントごとにデータエクスポートを分けてアカウントごとの S3 バケットに請求データを出力することもできます。

プログラマブルなデータさえ出力できれば、挙げた例の他にも如何様に自動処理が考えられると思います。

一方、メンバーアカウント側では自アカウントの請求データしか出力できず、複数アカウントがある場合には処理が煩雑になります。

ガバメントクラウドの AWS で Organizations のマスターアカウントを持つデジタル庁側で請求データを管理するのが、Organizations の機能的にも理に適っていると思います。

共同利用方式では地方自治体側で利用実績が確認できない問題を、一番手っ取り早く解決できる方法だと思います。ぜひ検討いただきたいです。ｼﾞｰｷｬｽ!!