新しくなったMicrosoft Cost Details APIを試してみた

## Cost Details APIとは
Cost Details APIは、Enterprise Agreement (EA) および Microsoft Customer Agreement (MCA) のユーザーが利用できるMicrosoft製品の利用料金に関わるAPIです。

以前までは、[EA Reporting API](https://docs.microsoft.com/en-us/azure/cost-management-billing/manage/enterprise-api) と [Consumption Usage Details API](https://docs.microsoft.com/en-us/rest/api/consumption/usage-details/list?tabs=HTTP)というAPIが提供されていましたが、今後積極的に開発されることはなく、廃止に向かっていくそうです。

当方はAzure EA契約の使用料金をEA Reporting APIで取得し、サブスクリプションごとに発生した料金を集計する運用を行っていましたが、Cost Details APIへの移行を検討せざるを得なくなりました。

## 何が変わったの？
[公式のブログ](https://azure.microsoft.com/ja-jp/blog/microsoft-cost-details-api-now-generally-available-for-ea-and-mca-customers/)によると以下の改善が行われているようです（一部抜粋）

- セキュリティと安定性
    - APIにアクセスするためにサービス プリンシパルやユーザートークンが必要になった。
    - 以前まではEAポータルから取得するトークンを使用しており、6カ月の有効期限を気にする必要があったが、Azure REST API と一貫性のある、サービス プリンシパルまたはユーザー認証によるトークン ベースのソリューションを使用することができるようになった。
- すべての使用状況の詳細に対する単一のデータセット
    - 既存の EA Reporting API には、Azure の使用料金と Azure Marketplace の料金に対して別々のエンドポイントがあった。
    - 単一のデータセットにより、すべての料金を確認するために呼び出す必要がある API の数が減ります。
- 継続的な改善
    - 新しいソリューションは積極的に開発されており、リリースされると、すべての新機能を受け取ることができる。
 
などなど、メリットもありますが、現時点で大きな変更だと感じているは、すべてのアウトプットがCSV形式でblobストレージに配置されるようになったことです。

Consumption Usage Details APIではレスポンスのBodyに実際に発生した金額明細が返却され、アプリケーション内で加工、集計が可能でした。
しかし新しいAPIでは生成されたCSVファイルが配置されたblobのURLが返却され、そのblobからCSVをダウンロードして明細を確認する必要があります。

これによって既存の運用で使用していたスクリプトは大きな変更を余儀なくされます。
今後のアップデートでデータフォーマットが拡充されることを期待します。

## 実際に触ってみた
何はともあれ、まだ旧APIの廃止日が決まったわけではありませんが、触ってみないとわからないことも多いので簡単に実行してみました。

### ユーザートークンを取得する
新しいAPIではBearerトークンで認証するため、トークンを取得します。
事前にaz loginしておき、Azure CLIで以下コマンドを実行
```powershell
az account get-access-token --tenant 00000000-0000-0000-0000-000000000000
```
テナントIDは自身のメインテナント

### お好みのRESTクライアントでAPIを実行
https://docs.microsoft.com/en-us/rest/api/cost-management/generate-cost-details-report/create-operation
```
curl --location --request POST 'https://management.azure.com/providers/Microsoft.Billing/billingAccounts/<EA契約加入番号>/providers/Microsoft.CostManagement/generateCostDetailsReport?api-version=2022-05-01' \
--header 'Authorization: Bearer <取得したトークン>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "metric": "ActualCost",
  "billingPeriod": "202206"
}'
```

202が帰ってくればOK

### レスポンスヘッダーからポーリング用のURLを確認
202レスポンスのヘッダーにLocationがあり、ポーリング用のURLが発行されている。
このURLにGETすることでアウトプットの状況がわかる。
※GET時もトークンの認証は必要

まだ完了していなければ202が同じように返却され、完了すると200が返却される。
※以前までのAPIと比べて対象月のすべての明細を生成するまでの時間が5倍程度短縮されたように感じます。

### blobから結果のCSVを取得
https://docs.microsoft.com/en-us/rest/api/cost-management/generate-cost-details-report/get-operation-results

200では以下のようなレスポンスBodyが返却される。

```json
{
  "id": "subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.CostManagement/costDetailsOperationResults/00000000-0000-0000-0000-000000000000",
  "name": "00000000-0000-0000-0000-000000000000",
  "status": "Completed",
  "manifest": {
    "manifestVersion": "2022-05-01",
    "dataFormat": "Csv",
    "blobCount": 1,
    "byteCount": 32741,
    "compressData": false,
    "requestContext": {
      "requestScope": "subscriptions/00000000-0000-0000-0000-000000000000",
      "requestBody": {
        "metric": "ActualCost",
        "timePeriod": {
          "start": "2020-03-01",
          "end": "2020-03-15"
        }
      }
    },
    "blobs": [
      {
        "blobLink": "https://ccmreportstorageeastus.blob.core.windows.net/armreports/00000/00000000-0000-0000-0000-000000000000?sv=2020-05-31&sr=b&sig=abcd",
        "byteCount": 32741
      }
    ]
  },
  "validTill": "2022-05-10T08:08:46.1973252Z"
}
```
blobLinkのURLにアクセスすることでCSVを取得することができます。
個人的にこのblobがパブリックになっているのでセキュリティ的な懸念もあります。
※validTillに設定されている日時までDLが可能なようです（約3時間）