ETL ツール TROCCO で始める AWS コスト分析ダッシュボード構築

AWS

2025.9.25

Topics

概要

本記事では、ETL ツール「TROCCO」を活用して、AWS Cost and Usage Reports (CUR) から BigQuery へのデータ転送を自動化し、Looker Studio で可視化するまでの一連の流れをご紹介します。

完成したダッシュボード

今回構築したシステムでは、月次の AWS コストが一目で確認できるダッシュボードを作成しました。
サービス別の利用料金やコストの推移を直感的に把握できます。

作成したAWS CURのダッシュボード

TROCCO について

TROCCO は、株式会社primeNumber が提供する ETL/データ転送サービスです。
コーディング不要で、データの抽出・変換・転送を自動化できることが大きな特徴です。

TROCCO(トロッコ) データ連携を自動にするクラウド ETL | primeNumber

主な機能は以下の通りです。

  • データ転送
    • 広告、データベース、ストレージ、SaaS など、国内外様々なソースから DWH へデータを転送します。
  • データマート生成
    • DWH 内のデータを分析しやすいように加工・集計し、データマートを生成します。
  • dbt との連携
    • データ変換ツールである dbt と連携し、より高度なデータモデリングも可能です。
  • 豊富なコネクタ
    • 100 種類以上のコネクタに対応しており、様々なデータソースとの連携が容易です。

今回のように AWS CUR のような複雑なデータでも、TROCCO を使えば BigQuery などのデータウェアハウスに簡単に転送し、その後のデータ加工までを自動化できます。
これにより、エンジニアでない担当者でも手軽にデータ分析基盤を構築・運用することが可能になります。

今回は、 Free プランのアカウントで作業を実施します。
料金プラン| TROCCO®︎(トロッコ)

データ分析基盤の構成

構成図は以下の通りです。
AWS CURからBigQueryへのETLフロー

作成の手順は以下の通りです。

  1. AWS CUR のコストデータを S3 にエクスポート
  2. TROCCO で ETL 処理をして BigQuery にデータを転送
  3. Looker Studio でデータを可視化

AWS CUR のコストデータを S3 にエクスポート

最初に、AWS CUR のデータエクスポート機能を使って S3 バケットへのデータのエクスポートを開始します。
エクスポート先の S3 バケットは事前に作成しておきます。

データエクスポートの作成 – AWS Data Exports

データエクスポートの設定項目は以下を選択します。

  • エクスポートタイプ:標準データエクスポート

CURエクスポート設定画面

  • データテーブルコンテンツ設定:CUR 2.0
    • 「リソース ID を含める」と「コスト配分データを分割」にチェックを入れる

CUR 2.0データテーブル設定

  • 時間粒度:日次

エクスポート時間粒度選択

  • データエクスポート配信オプション
    • 圧縮タイプとファイル形式:gzip-テキスト/csv
    • ファイルのバージョニング:既存のデータエクスポートファイルを上書き

データエクスポート配信設定

上記の設定でエクスポートされた CSV ファイルは以下の通りです。
※一部データ加工済み

bill_bill_type,bill_billing_entity,bill_billing_period_end_date,bill_billing_period_start_date,bill_invoice_id,bill_invoicing_entity,bill_payer_account_id,bill_payer_account_name,cost_category,discount,discount_bundled_discount,discount_total_discount,identity_line_item_id,identity_time_interval,line_item_availability_zone,line_item_blended_cost,line_item_blended_rate,line_item_currency_code,line_item_legal_entity,line_item_line_item_description,line_item_line_item_type,line_item_net_unblended_cost,line_item_net_unblended_rate,line_item_normalization_factor,line_item_normalized_usage_amount,line_item_operation,line_item_product_code,line_item_resource_id,line_item_tax_type,line_item_unblended_cost,line_item_unblended_rate,line_item_usage_account_id,line_item_usage_account_name,line_item_usage_amount,line_item_usage_end_date,line_item_usage_start_date,line_item_usage_type,pricing_currency,pricing_lease_contract_length,pricing_offering_class,pricing_public_on_demand_cost,pricing_public_on_demand_rate,pricing_purchase_option,pricing_rate_code,pricing_rate_id,pricing_term,pricing_unit,product,product_name,product_comment,product_fee_code,product_fee_description,product_from_location,product_from_location_type,product_from_region_code,product_instance_family,product_instance_type,product_instancesku,product_location,product_location_type,product_operation,product_pricing_unit,product_product_family,product_region_code,product_servicecode,product_sku,product_to_location,product_to_location_type,product_to_region_code,product_usagetype,reservation_amortized_upfront_cost_for_usage,reservation_amortized_upfront_fee_for_billing_period,reservation_availability_zone,reservation_effective_cost,reservation_end_time,reservation_modification_status,reservation_net_amortized_upfront_cost_for_usage,reservation_net_amortized_upfront_fee_for_billing_period,reservation_net_effective_cost,reservation_net_recurring_fee_for_usage,reservation_net_unused_amortized_upfront_fee_for_billing_period,reservation_net_unused_recurring_fee,reservation_net_upfront_value,reservation_normalized_units_per_reservation,reservation_number_of_reservations,reservation_recurring_fee_for_usage,reservation_reservation_a_r_n,reservation_start_time,reservation_subscription_id,reservation_total_reserved_normalized_units,reservation_total_reserved_units,reservation_units_per_reservation,reservation_unused_amortized_upfront_fee_for_billing_period,reservation_unused_normalized_unit_quantity,reservation_unused_quantity,reservation_unused_recurring_fee,reservation_upfront_value,cost_tag,savings_plan_amortized_upfront_commitment_for_billing_period,savings_plan_end_time,savings_plan_instance_type_family,savings_plan_net_amortized_upfront_commitment_for_billing_period,savings_plan_net_recurring_commitment_for_billing_period,savings_plan_net_savings_plan_effective_cost,savings_plan_offering_type,savings_plan_payment_option,savings_plan_purchase_term,savings_plan_recurring_commitment_for_billing_period,savings_plan_region,savings_plan_savings_plan_a_r_n,savings_plan_savings_plan_effective_cost,savings_plan_savings_plan_rate,savings_plan_start_time,savings_plan_total_commitment_to_date,savings_plan_used_commitment,split_line_item_actual_usage,split_line_item_net_split_cost,split_line_item_net_unused_cost,split_line_item_parent_resource_id,split_line_item_public_on_demand_split_cost,split_line_item_public_on_demand_unused_cost,split_line_item_reserved_usage,split_line_item_split_cost,split_line_item_split_usage,split_line_item_split_usage_ratio,split_line_item_unused_cost,transferred_time,resource_tags
Anniversary,AWS,2025-10-01 00:00:00.000000 UTC,2025-09-01 00:00:00.000000 UTC,,Amazon Web Services Japan G.K.,012345678912,NHNTechorus,{},{},,,wmsi77uwn5rplrpvcbzq,2025-09-05T00:00:00Z/2025-09-06T00:00:00Z,,0.0256000008,0.0960000000,USD,Amazon Web Services Japan G.K.,$0.096 per GB-month of General Purpose (gp3) provisioned storage - Asia Pacific (Tokyo),Usage,,,0.0,0.0,CreateVolume-Gp3,AmazonEC2,vol-03a98f0561c,,0.0256000008,0.096,148761661473,アカウント名,0.2666666664,2025-09-06 00:00:00.000000 UTC,2025-09-05 00:00:00.000000 UTC,APN1-EBS:VolumeUsage.gp3,USD,,,0.0256,0.0960000000,,JRTCKXETXF.6YS6EN2CT7,235045679946,OnDemand,GB-Mo,"{""max_volume_size"":""16 TiB"",""volume_type"":""General Purpose"",""storage_media"":""SSD-backed"",""servicename"":""Amazon Elastic Compute Cloud"",""product_name"":""Amazon Elastic Compute Cloud"",""max_iopsvolume"":""16000"",""volume_api_name"":""gp3"",""region"":""ap-northeast-1"",""max_throughputvolume"":""1000 MiB/s""}",Amazon Elastic Compute Cloud,,,,,,,,,,Asia Pacific (Tokyo),AWS Region,,,Storage,ap-northeast-1,AmazonEC2,3GTH8T5JV,,,,APN1-EBS:VolumeUsage.gp3,0.0,0.0,,0.0,,,,,,,,,,,,0.0,,,012345678912,,,,0.0,0.0,0.0,0.0,0.0,,0.0,,,,,,,,,0.0,,,0.0,0.0,,0.0,0.0,,,,,,,,,,,,2025-09-10 00:05:52.596000 UTC,{}
Anniversary,AWS,2025-10-01 00:00:00.000000 UTC,2025-09-01 00:00:00.000000 UTC,,Amazon Web Services Japan G.K.,012345678912,NHNTechorus,{},{},,,32xt4d452yenlf5yt35msu4iwa,2025-09-06T00:00:00Z/2025-09-07T00:00:00Z,,0.0031999992,0.0960000000,USD,Amazon Web Services Japan G.K.,$0.096 per GB-month of General Purpose (gp3) provisioned storage - Asia Pacific (Tokyo),Usage,,,0.0,0.0,CreateVolume-Gp3,AmazonEC2,vol-01f50691e3909d324,,0.0031999992,0.096,148761661473,アカウント名,0.0333333336,2025-09-07 00:00:00.000000 UTC,2025-09-06 00:00:00.000000 UTC,APN1-EBS:VolumeUsage.gp3,USD,,,0.0032,0.0960000000,,JRTCKXETXF.6YS6EN2CT7,235045679946,OnDemand,GB-Mo,"{""max_volume_size"":""16 TiB"",""volume_type"":""General Purpose"",""storage_media"":""SSD-backed"",""servicename"":""Amazon Elastic Compute Cloud"",""product_name"":""Amazon Elastic Compute Cloud"",""max_iopsvolume"":""16000"",""volume_api_name"":""gp3"",""region"":""ap-northeast-1"",""max_throughputvolume"":""1000 MiB/s""}",Amazon Elastic Compute Cloud,,,,,,,,,,Asia Pacific (Tokyo),AWS Region,,,Storage,ap-northeast-1,AmazonEC2,YBQTH8T5JV,,,,APN1-EBS:VolumeUsage.gp3,0.0,0.0,,0.0,,,,,,,,,,,,0.0,,,012345678912,,,,0.0,0.0,0.0,0.0,0.0,,0.0,,,,,,,,,0.0,,,0.0,0.0,,0.0,0.0,,,,,,,,,,,,2025-09-10 00:05:52.596000 UTC,"{""aws_created_by"":""AssumedRole:AROASFI3:cold-airflow""}"
Anniversary,AWS,2025-10-01 00:00:00.000000 UTC,2025-09-01 00:00:00.000000 UTC,,Amazon Web Services Japan G.K.,012345678912,NHNTechorus,{},{},,,wm3hq5ralrpvcbzq,2025-09-07T00:00:00Z/2025-09-08T00:00:00Z,,0.0256000008,0.0960000000,USD,Amazon Web Services Japan G.K.,$0.096 per GB-month of General Purpose (gp3) provisioned storage - Asia Pacific (Tokyo),Usage,,,0.0,0.0,CreateVolume-Gp3,AmazonEC2,vol-03a98f0561c,,0.0256000008,0.096,148761661473,アカウント名,0.2666666664,2025-09-08 00:00:00.000000 UTC,2025-09-07 00:00:00.000000 UTC,APN1-EBS:VolumeUsage.gp3,USD,,,0.0256,0.0960000000,,JRTCKXETXF.6YS6EN2CT7,235045679946,OnDemand,GB-Mo,"{""max_volume_size"":""16 TiB"",""volume_type"":""General Purpose"",""storage_media"":""SSD-backed"",""servicename"":""Amazon Elastic Compute Cloud"",""product_name"":""Amazon Elastic Compute Cloud"",""max_iopsvolume"":""16000"",""volume_api_name"":""gp3"",""region"":""ap-northeast-1"",""max_throughputvolume"":""1000 MiB/s""}",Amazon Elastic Compute Cloud,,,,,,,,,,Asia Pacific (Tokyo),AWS Region,,,Storage,ap-northeast-1,AmazonEC2,JZTH8T5JV,,,,APN1-EBS:VolumeUsage.gp3,0.0,0.0,,0.0,,,,,,,,,,,,0.0,,,012345678912,,,,0.0,0.0,0.0,0.0,0.0,,0.0,,,,,,,,,0.0,,,0.0,0.0,,0.0,0.0,,,,,,,,,,,,2025-09-10 00:05:52.596000 UTC,{}

設定完了後、約 24 時間で S3 にファイルが生成されます。

AWS CUR のファイルの中身について

AWS CUR の設定で、特に重要なのがファイルのバージョニングです。

  • AWS CUR は 1 日に 1 回以上更新される仕様
  • 「新しいファイルを作成」だとほぼ同じデータが複数ファイルで作成される
  • データの一意性(最新データ)確保が困難になる

「既存のデータエクスポートファイルを上書き」を選択することで、月ごとのフォルダに 1 つのファイルが生成され、最新のデータを特定するのが楽になります。

「新しいデータエクスポートファイルを作成」を選択すると以下のように、同日に多数のフォルダが生成される形となります。
S3バケット内CURファイル一覧

各フォルダの中身は、CSV ファイルが一つあるだけです。
CURファイルオブジェクト詳細

「既存のデータエクスポートファイルを上書き」を選択すると、月ごとのフォルダ配下に CSV ファイルが生成されます。
圧縮されたCURファイル表示

TROCCO で ETL 処理をして BigQuery にデータを転送

今回 TROCCO で行う設定項目は以下の通りです。

  • 接続情報(S3,BigQuery)
  • データ転送設定
  • 通知設定
  • スケジュール設定

なお、BigQuery はデータセットまで事前に作成しておきます。

接続情報の設定

データを取得する S3 と転送先の BigQuery の認証情報を作成します。

S3 接続設定

IAM ロールを使用して S3 への接続を設定します。

TROCCO S3接続設定画面

詳細な手順は以下をご覧ください。
接続情報 – Amazon S3

権限は必要に応じてご選択ください。
Amazon S3 の AWS マネージドポリシー – Amazon Simple Storage Service

BigQuery 接続設定

サービスアカウントの JSON キーを使用して BigQuery への接続を設定します。

今回権限は以下の通りに設定しました。
必要な権限については、BigQuery の IAM ロールと権限を参照し必要に応じてご選択ください。

BigQueryロール設定画面

秘密鍵を払い出します。

サービスアカウント秘密鍵作成

払い出した、JSON Key を設定します。

TROCCO BigQuery接続設定画面

接続テストを行い、接続が問題ないことを確認します。

BigQuery接続テスト結果

接続情報 – Google BigQuery

転送設定

先程作成した接続情報を使用して転送設定を作成します。

S3からBigQuery転送設定

STEP1 転送元・転送先の設定

設定項目は以下の通りです。

  • パスプレフィックス: 下位階層まで指定
    • CSV ファイル以外に、メタデータも生成されるため、上位の階層で指定すると不要なファイルも連携されてエラーになります

バケット名とパス指定

S3 のファイル構成は以下の通りです。

フォルダ構造表示

  • 自動データ設定: 転送元の設定に基づいて自動抽出
    • 今回設定した AWS CUR だとカラム数が 120 個を超えているため一つずつ設定する手間を省きます

転送元設定自動抽出

  • 解凍形式: 非圧縮ファイルまたは bzip2/gzip
    • CSV ファイルは S3 に gzip 形式で格納されているので、「非圧縮ファイルまたは bzip2/gzip」を選択します

非圧縮ファイル設定

  • 入力ファイル形式: CSV/TSV
    • ヘッダー行を含む CSV ファイルになっています

CSV/TSVヘッダー設定

  • 転送方法: 差分転送(最終更新時間)
    • AWS CUR が今月のデータ以外も更新されていたため、最終更新時間を選択しました

差分転送(更新時間)

  • データセットの自動生成: dataset を自動で作成する

追記モード転送設定

STEP2 データプレビュー・詳細設定

しばらく待つとプレビューが表示されます。

データプレビュー画面

カラム定義を自動判定してくれますが、型の修正が必要な場合があります。

データ型とカラム設定

AWS CUR の画面で各列と型、説明を確認しながら変更してください。
今回、主に変更した内容は、「long」と認識されていた型を「string」に変更しました。

カラム選択とデータ型一覧

特別な処理が必要なカラムについて詳細を記載します。

product 列の処理

product 列には以下のように JSON 形式でデータが格納されているため、サービス名を抽出する必要があります。

{"servicename":"AWS WAF","product_name":"AWS WAF","group_description":"Web ACL Activated","region":"global","group":"Web ACL"}

JSON形式データ展開設定

resource_tags 列の処理
コストタグのデータが格納されており、分析軸として活用するため別カラムとして切り出します。

{"user_chorus_cost_tag1":"cold-airflow"}

リソースタグJSON展開

最後に、転送日時のカラムを設定します。

転送日時カラムを設定する背景として、日次で生成される AWS CUR データの一意性確保が困難だったため、TROCCO の転送日時カラムと AWS CUR の日次更新の上書き設定を組み合わせることで解決しました。
S3 に数日間の AWS CUR データがある場合は、まとめて転送すると転送日時カラムが全部同日になって一意に決まらなくなるので注意が必要です。

転送時刻カラム追加設定

もし、「転送日時カラム設定」を行ったあとで、カラムのエラーが発生するようであれば、BigQuery のテーブルにカラムを追加してください。

この設定でジョブを実行すれば、BigQuery 上にデータが転送されてます。

BigQueryでCURデータクエリ実行

スケジュールの登録

AWS CUR が日次で更新されるため、ジョブを毎日実行するスケジュールを設定します。

ジョブスケジュール設定画面

通知設定

ジョブ結果を Slack に通知する設定を行います。

事前に Slack Webhook を作成してください。
クイックスタート | Slack

ジョブ終了時の通知を設定します。
ジョブ終了時の通知設定画面

Slack通知設定画面

設定完了後、以下のような通知が届きます。

 AWS-CUR-TESTの転送完了通知

Looker Studio でデータを可視化

最後に BigQuery 上にあるデータを Looker Studio で可視化します。
Looker Studio: Business Insights Visualizations | Google Cloud

BigQuery をデータソースとして Looker Studio に連携します。
Looker Studio でデータを分析する  |  BigQuery  |  Google Cloud

データの前処理

転送日時カラムがタイムスタンプで扱いづらいため、日付に変換します。

データ型選択とフィールド設定

ダッシュボードの作成

作成したダッシュボードは、データの全体像を効率的に把握できるよう、4 つのグラフを作成しました。

作成したAWS CURのダッシュボード

コストサマリー

ダッシュボード左上に配置したサマリーセクションでは、総コストを大きな数値で表示し、一目で全体の規模を把握できるようにしています。
その下に円グラフを配置することで、各項目の構成比を視覚的に表現しており、全体に占める割合を直感的に理解できます。

AWSコスト内訳円グラフ

トレンド分析

中央部分のトレンド分析セクションでは、時系列データを棒グラフで表示しています。
横軸に日付、縦軸にコストを設定し、一定期間における推移パターンを可視化しました。

日別コスト推移グラフ

サービス別ランキング

右上のランキングセクションでは、上位項目を降順でテーブル表示しています。
具体的な項目名と数値を並べることで、どの要素が全体に大きく影響しているかを明確に示しています。

コスト集計サマリー表

詳細データセクション

ダッシュボード下部の詳細データセクションでは、全ての項目を網羅的にテーブル形式で表示しています。
各種属性情報を一覧化し、深掘り分析が必要な場合に活用できるようにしています。

AWSサービス別コスト表

まとめ

本記事では、TROCCO を使用した AWS コストデータの分析基盤構築について解説しました。
ノーコードツールの活用により、従来は複雑だったデータパイプライン構築が大幅に簡素化されることを実感いただけたのではないでしょうか。

特に、データエンジニア以外の方でも手軽にデータ分析基盤を構築できる点は、TROCCO の大きな魅力です。

NHN テコラスの採用情報はこちら

テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!

Cold-Airflow

2021年新卒入社。インフラエンジニアです。RDBが三度の飯より好きです。 主にデータベースやAWSのサーバレスについて書く予定です。あと寒いのは苦手です。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら