Microsoft Azure のコスト分析自動エクスポート機能を使って利用料金明細データを出力し、Amazon Athena で観察してみた

2023.01.14

いわさです。

複数のパブリッククラウドを利用している場合にコスト管理を特定のクラウドサービスや SaaS で集約管理したいケースは多いと思います。
私は普段 AWS をよく使っており、たまに Microsoft Azure を使うことがあります。
頻繁にアクセスする AWS の場合は毎日マネジメントコンソールへサインインするので現在どの程度利用しているのか把握出来ますが、AWS より利用頻度の低い Microsoft Azure のコストはたまに見落とすことがありますので AWS 上で Azure のコストを管理出来るとありがたい。

Microsoft Azure には Azure 外部でコストを管理出来るように、サブスクリプションごとの利用料金の明細データを定期的に自動エクスポートするマネージドな機能が備わっています。

今回はこちらを使って Azure のコスト明細 CSV を出力し、まずは手動で Amazon S3 へ取り込んで Athena で参照するところまで試してみました。
コスト明細 CSV がどのような感じで出力されるか、Athena でアクセスするためにはどのようにするのが良いのかなどを紹介します。

サブスクリプションごとにコスト分析から自動エクスポート設定出来る

サブスクリプションごとにエクスポート設定が必要ですが設定はとても簡単です。
Azure Blob Storage へエクスポートする形になるので事前にストレージアカウントなどを作成しました。(エクスポート設定から新規作成するオプションもあるようです)

サブスクリプションのコスト分析メニューからサブスクリプション構成メニューを開きます。

いくつかのコスト管理機能が表示されるのでエクスポートを選択します。

登録されているエクスポートタスクがリスト表示されますので、メニューから新規追加を行いましょう。

エクスポートにはいくつかタイプがあります。

  • [月度累計コストの日単位のエクスポート] - 月度累計コストに関する新しいエクスポート ファイルが毎日提供されます。 最新のデータは、以前の毎日のエクスポートから集計されます。
  • [過去 7 日間のコストの週単位のエクスポート] - 選択したエクスポートの開始日からさかのぼって 7 日間のコストに関するエクスポートが週単位で作成されます。
  • [先月のコストに関する月単位のエクスポート] - エクスポートを作成している月の前月のコストに関するエクスポートが提供されます。 それ以降は、スケジュールによって、毎月 5 日に前月分のコストを使用してエクスポートが実行されます。
  • [ワンタイム エクスポート] - 履歴データの日付範囲を選択して、Azure Blob Storage にエクスポートすることができます。 選択した日付から最大 90 日間の履歴コストをエクスポートできます。 このエクスポートはすぐに実行され、2 時間以内にストレージ アカウント内で利用できます。 エクスポートの種類に応じて、開始日を選択するか、 [開始日] と To の日付を選択します。

後の検証結果を見て頂くとわかるのですが、どのタイプでも出力されるフォーマットは同じで、エクスポートタイミングとエクスポートされる明細の対象期間が異なるだけです。

今回は 4 つのタイプすべて登録してみました。

カスタムの OneTime タスクはドキュメントのとおり数時間後に出力され、Monthly エクスポートタスクは来月の 5 日が次回実行予定の日時として登録されました。

Blob コンテナーにエクスポートされた CSV ファイルを確認

エクスポート設定から約 3 日後、指定した Blob コンテナーにいくつかの CSV ファイルが生成されていました。
日次エクスポートは 3 つのファイルが作成されています。3 日分っぽいですね。
Azure Blob Storage からダウンロードした際の構造は以下でした。

export がコンテナで、その直下の daily onetime weekly は私のほうで用意したフォルダです。
それより下がエクスポートタスクによって作成されたものになります。

どうやら「タスク名 - 抽出期間 - タスク名_UUID.csv」という構造で出力されるようです。
OneTime の抽出期間は手動で指定したもので、それ以外は自動です。
Daily の場合は対象月の 1 日から末日までで抽出されうようですね。
Weekly は実行日からさかのぼって 1 週間というところでしょうか。

ファイル構造も確認してみましょう。
どのタイプのファイルも以下のような構成の CSV ファイルでした。
明細の粒度としては日ごとの料金発生種別ごとの利用料金になっています。
時間の単位としては「日」になっているので「時間」単位での算出は難しそうです。

SubscriptionGuid,ResourceGroup,ResourceLocation,UsageDateTime,MeterCategory,MeterSubcategory,MeterId,MeterName,MeterRegion,UsageQuantity,ResourceRate,PreTaxCost,ConsumedService,ResourceType,InstanceId,Tags,OfferId,AdditionalInfo,ServiceInfo1,ServiceInfo2,ServiceName,ServiceTier,Currency,UnitOfMeasure
52332F67-77AE-48CA-A81F-3F37E3FFF0CC,cloud-shell-storage-southeastasia,AP Southeast,2023-01-08,Storage,Tiered Block Blob,99f50f54-1802-4465-9a21-b80f328e4fad,All Other Operations,AP Southeast,0.0006,0.448,0.0002688,Microsoft.Storage,Microsoft.Storage/storageAccounts,/subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/cloud-shell-storage-southeastasia/providers/Microsoft.Storage/storageAccounts/cs110033fff942285d4,"{""ms-resource-usage"":""azure-cloud-shell""}",,,,,Storage,Blob Storage,JPY,1000000
52332F67-77AE-48CA-A81F-3F37E3FFF0CC,cloud-shell-storage-southeastasia,AP Southeast,2023-01-07,Storage,Tiered Block Blob,99f50f54-1802-4465-9a21-b80f328e4fad,All Other Operations,AP Southeast,0.0004,0.448,0.0001792,Microsoft.Storage,Microsoft.Storage/storageAccounts,/subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/cloud-shell-storage-southeastasia/providers/Microsoft.Storage/storageAccounts/cs110033fff942285d4,"{""ms-resource-usage"":""azure-cloud-shell""}",,,,,Storage,Blob Storage,JPY,1000000
52332F67-77AE-48CA-A81F-3F37E3FFF0CC,cloud-shell-storage-southeastasia,AP Southeast,2023-01-09,Storage,Files,ed8a651a-e0a3-4de6-a8ae-3b4ce8cb72cf,LRS Data Stored,,0.16128,6.72,1.0838016,Microsoft.Storage,Microsoft.Storage/storageAccounts,/subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/cloud-shell-storage-southeastasia/providers/Microsoft.Storage/storageAccounts/cs110033fff942285d4,"{""ms-resource-usage"":""azure-cloud-shell""}",,,,,Storage,Files,JPY,100 GB/Month
52332F67-77AE-48CA-A81F-3F37E3FFF0CC,hoge0109,JA East,2023-01-09,Storage,Files,761abab8-259d-4206-a6ae-707ed03fc540,Read Operations,,0.0004,0.168,0.0000672,Microsoft.Storage,Microsoft.Storage/storageAccounts,/subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/hoge0109/providers/Microsoft.Storage/storageAccounts/hoge0109azure,,,,,,Storage,Files,JPY,10000000
52332F67-77AE-48CA-A81F-3F37E3FFF0CC,cloud-shell-storage-southeastasia,AP Southeast,2023-01-04,Storage,Tables,3f2b1e1c-c886-4ec6-ad6f-dd0ef38819c9,LRS Data Stored,,0.000117,5.0399999999999991,0.00058968,Microsoft.Storage,Microsoft.Storage/storageAccounts,/subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/cloud-shell-storage-southeastasia/providers/Microsoft.Storage/storageAccounts/cs110033fff942285d4,"{""ms-resource-usage"":""azure-cloud-shell""}",,,,,Storage,Tables,JPY,100 GB/Month
52332F67-77AE-48CA-A81F-3F37E3FFF0CC,cloud-shell-storage-southeastasia,AP Southeast,2023-01-08,Storage,Tables,b9e5e77c-a0b3-4a2c-9b8b-57fa54f31c52,Batch Write Operations,,0.0146,0.04032,0.000588672,Microsoft.Storage,Microsoft.Storage/storageAccounts,/subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/cloud-shell-storage-southeastasia/providers/Microsoft.Storage/storageAccounts/cs110033fff942285d4,"{""ms-resource-usage"":""azure-cloud-shell""}",,,,,Storage,Tables,JPY,100000000
52332F67-77AE-48CA-A81F-3F37E3FFF0CC,cloud-shell-storage-southeastasia,AP Southeast,2023-01-08,Storage,Tables,3f2b1e1c-c886-4ec6-ad6f-dd0ef38819c9,LRS Data Stored,,0.00012,5.0399999999999991,0.0006048,Microsoft.Storage,Microsoft.Storage/storageAccounts,/subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/cloud-shell-storage-southeastasia/providers/Microsoft.Storage/storageAccounts/cs110033fff942285d4,"{""ms-resource-usage"":""azure-cloud-shell""}",,,,,Storage,Tables,JPY,100 GB/Month
52332F67-77AE-48CA-A81F-3F37E3FFF0CC,cloud-shell-storage-southeastasia,AP Southeast,2023-01-10,Storage,Files,ed8a651a-e0a3-4de6-a8ae-3b4ce8cb72cf,LRS Data Stored,,0.12768,6.72,0.8580096,Microsoft.Storage,Microsoft.Storage/storageAccounts,/subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/cloud-shell-storage-southeastasia/providers/Microsoft.Storage/storageAccounts/cs110033fff942285d4,"{""ms-resource-usage"":""azure-cloud-shell""}",,,,,Storage,Files,JPY,100 GB/Month
52332F67-77AE-48CA-A81F-3F37E3FFF0CC,common,Unknown,2023-01-07,Azure DNS,,8f967c58-b144-4bd7-8882-8bf02767c839,Public Zone,,0.032258064516129,55.999999999999893,1.806451612903224,Microsoft.Network,Microsoft.Network/dnszones,/subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/common/providers/Microsoft.Network/dnszones/iwasahoge.net,,,,,,Azure DNS,Azure DNS,JPY,2
:

CSV のカラムヘッダーは以下のようになっていました。

列ヘッダ 値の例
SubscriptionGuid 52332F67-77AE-48CA-A81F-3F37E3FFF0CC
ResourceGroup common
ResourceLocation JA East
UsageDateTime 2023-01-11
MeterCategory Storage
MeterSubcategory Tiered Block Blob
MeterId a8e5826f-0b33-4241-8ceb-6e94e10994bf
MeterName Hot LRS Write Operations
MeterRegion JA East
UsageQuantity 0.0009
ResourceRate 5.6
PreTaxCost 0.00504
ConsumedService Microsoft.Storage
ResourceType Microsoft.Storage/storageAccounts
InstanceId /subscriptions/52332F67-77AE-48CA-A81F-3F37E3FFF0CC/resourceGroups/common/providers/Microsoft.Storage/storageAccounts/iwasaazurecost
Tags ※私の環境だと観測できませんでした...
OfferId ※私の環境だと観測できませんでした...
AdditionalInfo ※私の環境だと観測できませんでした...
ServiceInfo1 ※私の環境だと観測できませんでした...
ServiceInfo2 ※私の環境だと観測できませんでした...
ServiceName Storage
ServiceTier Blob Storage
Currency JPY
UnitOfMeasure 1000000

Amazon Athena で確認してみる

特に理由は無いですが慣れていたので Athena でいくつかクエリをかけてみました。

ちなみに Athena の Create Table は以下のような感じで作成しました。
Glue Crawler で適当にクローリングしただけなのですが、先程の CSV レイアウトからすると悪くない気がします。

CREATE EXTERNAL TABLE `onetimeonetime`(
  `subscriptionguid` string, 
  `resourcegroup` string, 
  `resourcelocation` string, 
  `usagedatetime` string, 
  `metercategory` string, 
  `metersubcategory` string, 
  `meterid` string, 
  `metername` string, 
  `meterregion` string, 
  `usagequantity` double, 
  `resourcerate` double, 
  `pretaxcost` double, 
  `consumedservice` string, 
  `resourcetype` string, 
  `instanceid` string, 
  `tags` struct<ms-resource-usage:string>, 
  `offerid` string, 
  `additionalinfo` string, 
  `serviceinfo1` string, 
  `serviceinfo2` string, 
  `servicename` string, 
  `servicetier` string, 
  `currency` string, 
  `unitofmeasure` string)
ROW FORMAT DELIMITED 
  FIELDS TERMINATED BY ',' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  's3://hoge0114azurecost/onetime/'
TBLPROPERTIES (
  'CrawlerSchemaDeserializerVersion'='1.0', 
  'CrawlerSchemaSerializerVersion'='1.0', 
  'UPDATED_BY_CRAWLER'='azure-cost-crawler', 
  'areColumnsQuoted'='false', 
  'averageRecordSize'='433', 
  'classification'='csv', 
  'columnsOrdered'='true', 
  'compressionType'='none', 
  'delimiter'=',', 
  'objectCount'='1', 
  'recordCount'='99', 
  'sizeKey'='42973', 
  'skip.header.line.count'='1', 
  'typeOfData'='file')

だいたい 1200 円強の料金が算出されれば良さそうですがどうでしょうか。

悪く無さそうです。

サービス別に集計

Azure ポータルのコスト分析画面の InvoiceDetails 形式だと以下のようになりますが、このレベルで集約してみましょう。

ちょっと誤差があります。
エクスポートする際の当日データが何時まで含まれているのかで誤差が発生しているとかでしょうかね。わからないです。
でも悪くないですね。コスト管理に利用出来るレベルだと思います。

日次出力ファイルを比較してみる

おまけに、日次出力されるファイルが今回 3 日分ということで 3 つ取得出来ました。
こちらを日別にグルーピングして比較してみましょう。

ドキュメントには「初回のエクスポートが実行されるまで 12 ~ 24 時間かかる」と記載されています。
タスクを作成したのが 2023 年 1 月 11 日 11:30 ごろなので、私の場合は 15 時間ほどかかったようです。

2023 年 1 月 12 日 2:19 AM JST に出力されたもの

1 月 1 日から 1 月 10 日までのデータが出力されています。
UTC だと 1 月 11 日 17 時がエクスポートタイミングということなので、前日の 1 月 10 日までの利用料金が出力されるという感じだろうか。
いずれにせよ数日のタイムラグがあるという点を覚えておいたほうが良さそうです。

2023 年 1 月 13 日 2:19 AM JST に出力されたもの

1 月 13 日のエクスポートデータでは 1 月 11 日の利用料金データも追加されました。
日次の出力ファイルはその時点までの当月のエクスポートデータなので外部システムで最新の料金にアクセスする際は全ての日次 CSV にアクセスする必要は無いですね。ファイル名から最新のものがどれかというのがわからないが...

2023 年 1 月 14 日 2:19 AM JST に出力されたもの

1 月 14 日のエクスポートデータも同じ感じです。
ただしよく見ると 1 月 11 日の料金が変わっていますね。原因分析にもう少し明細データの比較をしたほうが良さそうですが次回やってみます。

さいごに

今回は Microsoft Azure のコスト分析自動エクスポート機能を使って利用料金明細データを出力し、Amazon Athena で観察してみたので、どういう使い方でどういうデータが出力出来るのかを紹介しました。

Athena でサービスごと日ごとの利用料金などが算出出来そうなので、ここから分析や可視化が出来そうですね。
今回は手動で S3 に配置して Athena から参照しましたが、次回以降はエクスポートデータを自動でストレージ間同期させて QuickSight で可視化するところまでトライしてみたいなと思います。