Cost Management のデータを API で取得する

azure
Published: 2025-06-05

はじめに

所有者権限を持っている複数のサブスクリプションの料金を Cost Management で集計したくなりました。ですが、私の環境では Cost Management のスコープを管理グループにしても料金が表示されません。どうも CSP サブスクリプションでも同じように Cost Management のスコープとして管理グループを利用できないようです。

CSP スコープの管理グループは、Cost Management ではサポートされません。 CSP サブスクリプションを利用していて、コスト分析でそのスコープを管理グループに設定した場合、次のようなエラーが表示されます。

スコープを理解して使用する

「それなら API 直叩きで情報を取得して CSV ファイルを生成してからの Excel で集計すればいいじゃない」という発想で調べた結果をまとめます。

実践

開発者ツールを開きながら Cost Management の画面を操作すると、Cost Management に表示されている情報が次の API で取得されていることが分かります。

Query - Usage

この API を使う際には、「こんな観点で集計した情報をくれ」という情報を含む JSON を送信する必要があります。

例えば、今月のリソースグループ毎の料金を取得したい場合には、次のような JSON を送信する必要があります。

$uri = "https://management.azure.com/subscriptions/SUBSCRIPTION-ID/providers/Microsoft.CostManagement/query?api-version=2021-10-01"

$body = @"
{
  "type": "Usage",
  "timeframe": "BillingMonthToDate",
  "dataset": {
    "granularity": "None",
    "aggregation": {
      "totalCost": {
        "name": "Cost",
        "function": "Sum"
      },
      "totalCostUSD": {
        "name": "CostUSD",
        "function": "Sum"
      }
    },
    "grouping": [
      {
        "type": "Dimension",
        "name": "ResourceGroup"
      }
    ]
  }
}
"@
Invoke-AzRestMethod -Uri $uri -Payload $body -Method POST 

次のような情報が返ってきます。rows に含まれる配列に金額と集計要素であるリソースグループ名が含まれているので、split で分解すれば Powershell スクリプト内で利用できます。

StatusCode : 200
Content    : {
               "id": "subscriptions/SUBSCRIPTION-ID/providers/Microsoft.CostManagement/query/422dff96-5e67-41f5-9182-510fa62f5970",        
               "name": "422dff96-5e67-41f5-9182-510fa62f5970",
               "type": "Microsoft.CostManagement/query",
               "location": null,
               "sku": null,
               "eTag": null,
               "properties": {
                 "nextLink": null,
                 "columns": [
                   {
                     "name": "Cost",
                     "type": "Number"
                   },
                   {
                     "name": "CostUSD",
                     "type": "Number"
                   },
                   {
                     "name": "ResourceGroup",
                     "type": "String"
                   },
                   {
                     "name": "Currency",
                     "type": "String"
                   }
                 ],
                 "rows": [
                   [
                     0.075844,
                     0.075844,
                     "",
                     "USD"
                   ],
                   [
                     5.96752666600773,
                     5.96752666600773,
                     "acs",
                     "USD"
                   ],
                   [
                     0.97,
                     0.97,
                     "rg-nsp-eval",
                     "USD"
                   ],
                   [
                     38.3369490781043,
                     38.3369490781043,
                     "test",
                     "USD"
                   ]
                 ]
               }
             }

任意の期間の料金を取得したい場合には、timeframe を Custom にしたうえで timePeriod で From と To を指定します。

$body = @"
{
  "type": "Usage",
  "timeframe": "BillingMonthToDate",
  "timePeriod": {
    "from":"2025-05-01T00:00:00+00:00",
    "to":"2025-05-15T23:59:59+00:00"
  },
  "dataset": {
    "granularity": "None",
    "aggregation": {
      "totalCost": {
        "name": "Cost",
        "function": "Sum"
      },
      "totalCostUSD": {
        "name": "CostUSD",
        "function": "Sum"
      }
    },
    "grouping": [
      {
        "type": "Dimension",
        "name": "ResourceGroup"
      }
    ]
  }
}
"@

リソースごとの料金が必要であればこんな感じです。grouping の中の Dimension を集計したい要素に変えれば OK です。

$body = @"
{
    "type": "ActualCost",
    "timeframe": "BillingMonthToDate",
    "dataSet": {
        "granularity": "None",
        "aggregation": {
            "totalCost": {
                "name": "Cost",
                "function": "Sum"
            },
            "totalCostUSD": {
                "name": "CostUSD",
                "function": "Sum"
            }
        },
        "grouping": [
            {
                "type": "Dimension",
                "name": "ResourceId"
            }
        ]
    }
}
"@

今現在の料金を取得したければ、次のような形になります。

$body=@"
{
    "type": "ActualCost",
    "timeframe": "BillingMonthToDate",
    "dataSet": {
        "granularity": "None",
        "aggregation": {
            "totalCost": {
                "name": "Cost",
                "function": "Sum"
            },
            "totalCostUSD": {
                "name": "CostUSD",
                "function": "Sum"
            }
        }
    }
}
"@

次のように rows の配列の中に1つだけ値が存在した結果が返ってきます。

StatusCode : 200
Content    : {
               "id": "subscriptions/SUBSCRIPTION-ID/providers/Microsoft.CostManagement/query/9a276f98-cb71-43cf-812f-ec26bb86b5fc",
               "name": "9a276f98-cb71-43cf-812f-ec26bb86b5fc",
               "type": "Microsoft.CostManagement/query",
               "location": null,
               "sku": null,
               "eTag": null,
               "properties": {
                 "nextLink": null,
                 "columns": [
                   {
                     "name": "Cost",
                     "type": "Number"
                   },
                   {
                     "name": "CostUSD",
                     "type": "Number"
                   },
                   {
                     "name": "Currency",
                     "type": "String"
                   }
                 ],
                 "rows": [
                   [
                     152.06505596681,
                     152.06505596681,
                     "USD"
                   ]
                 ]
               }
             }

GUI 上で確認できる料金は $152 なので、意図した情報を取れています。

Cost Management 上での現時点での料金

JSON の dataSet 内にどのような値を入れればいいかは、見たい操作を GUI で行いつつ、開発者ツールを使って送信された値を確認するのが楽です。

開発者ツールでの確認

今月の日次の利用料金を取得した場合には次のような JSON が飛んでいました。

$body = @"
{
    "type": "ActualCost",
    "dataSet": {
        "granularity": "Daily",
        "aggregation": {
            "totalCost": {
                "name": "Cost",
                "function": "Sum"
            },
            "totalCostUSD": {
                "name": "CostUSD",
                "function": "Sum"
            }
        },
        "sorting": [
            {
                "direction": "ascending",
                "name": "UsageDate"
            }
        ]
    },
    "timeframe": "Custom",
    "timePeriod": {
        "from": "2025-06-01T00:00:00+00:00",
        "to": "2025-06-30T23:59:59+00:00"
    }
}
"@

この JSON を送信すると、次のような日付毎の金額を含む配列が返ってきます。rows に含まれる配列に金額と日付が含まれているので、split で分解すれば Powershell スクリプト内で利用できます。

StatusCode : 200
Content    : {
               "id": "subscriptions/SUBSCRIPTION-ID/providers/Microsoft.CostManagement/query/2421de4a-24cc-442f-8882-b34165403975",
               "name": "2421de4a-24cc-442f-8882-b34165403975",
               "type": "Microsoft.CostManagement/query",
               "location": null,
               "sku": null,
               "eTag": null,
               "properties": {
                 "nextLink": null,
                 "columns": [
                   {
                     "name": "Cost",
                     "type": "Number"
                   },
                   {
                     "name": "CostUSD",
                     "type": "Number"
                   },
                   {
                     "name": "UsageDate",
                     "type": "Number"
                   },
                   {
                     "name": "Currency",
                     "type": "String"
                   }
                 ],
                 "rows": [
                   [
                     35.246181365791,
                     35.246181365791,
                     20250601,
                     "USD"
                   ],
                   [
                     35.1927764530089,
                     35.1927764530089,
                     20250602,
                     "USD"
                   ],
                   [
                     37.5482007207832,
                     37.5482007207832,
                     20250603,
                     "USD"
                   ],
                   [
                     39.6806796582235,
                     39.6806796582235,
                     20250604,
                     "USD"
                   ],
                   [
                     2.78708736921931,
                     2.78708736921931,
                     20250605,
                     "USD"
                   ]
                 ]
               }
             }

まとめ

Cost Management のデータを API 経由で取得する方法をまとめました。地味ですが意外と使いどころありそうな気がしています。

Note

  • 当サイトは個人のブログです。このブログに示されている見解や意見は個人的なものであり、所属組織の見解や意見を表明するものではありません。
  • 公開情報を踏まえて正確な情報を掲載するよう努めますが、その内容の完全性や正確性、有用性、安全性、最新性について一切保証しません。
  • 添付文章やリンク先などを含む本サイトの内容は作成時点でのものであり、予告なく変更される場合があります。