0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DataExportを使ってCUR2.0を自分好みにカスタマイズする

0
Last updated at Posted at 2026-05-06

はじめに

 皆さんはCUR、活用していますでしょうか。FinOps実践のための第一歩であり、とりあえず有効化されている方は多いんじゃないかと思います。AWSのコスト管理において、CUR(Cost and Usage Report) はコストの詳細を把握するための基本的なデータソースです。2023年末には後継として CUR 2.0 が登場し、現在は AWS BCM Data Exports というサービスを通じて管理・設定を行います。

 Data Exportsには、マネジメントコンソールから操作できる機能に加えて、CLIを利用することで初めて使える機能 がいくつか存在します。その中でも特に活用できるのが、エクスポートするデータをSQLクエリで絞り込める機能 です。エクスポートするカラムを選択したり、WHERE句で特定の条件に合う行だけをエクスポートしたりすることが可能で、この機能を使いこなすことでコストや運用効率を改善できます。

 本記事では、CURをカスタマイズするとどんな嬉しいことがあるのかを説明した後、Data ExportsでSQLクエリを設定するための具体的な手順をステップバイステップで紹介します。

CUR 2.0 / Data Exportsのおさらい

 まず、そもそもCURとDataExportとは何なのかについておさらいしていきます。

CUR とは

 CUR(Cost and Usage Report)は、AWSの利用コストと使用量の詳細データをS3にエクスポートする機能です。ラインアイテム単位(サービス・アカウント・リージョン・リソースごと)の詳細なコストデータを持ち、Athena/Glueと組み合わせてコスト分析に広く活用されています。

 さらに、従来のCURの後継として CUR 2.0 の提供が開始されました。CUR 2.0はAWS BCM Data Exports(Billing and Cost Management Data Exports)というサービスから管理します。CUR 2.0ではParquetフォーマットへの対応や、新しいカラムの追加など、いくつかの改善が加えられています。

Data Exportsで扱えるテーブル

 Data Exportsでは、複数のテーブルからデータをエクスポートできます。主なものは以下の通りです。

テーブル名 説明
COST_AND_USAGE_REPORT CUR 2.0。コストと使用量の詳細データ(本記事の主役)
COST_AND_USAGE_DASHBOARD CIDなど各種ダッシュボード向けのビュー
FOCUS_1_2_AWS FinOps Open Cost & Usage Specification形式
CARBON_EMISSIONS カーボンエミッションデータ
COST_OPTIMIZATION_RECOMMENDATIONS Cost Optimization Hub のレコメンデーション

 本記事では、COST_AND_USAGE_REPORTテーブル(CUR 2.0)を対象とします。

CURをカスタマイズすると嬉しいこと

 では、本題です。CURをSQLでカスタマイズすることで、具体的にどのようなメリットがあるのでしょうか。

① S3ストレージコストの削減

 CUR 2.0のCOST_AND_USAGE_REPORTテーブルには、100列以上のカラムが存在します。しかし、実際のコスト分析でこれら全列を使うことはほとんどなく、多くの場合は数十列もあれば十分なはずです。

 デフォルト設定では全列がエクスポートされますが、SQLのSELECT句で必要なカラムのみを指定することで、エクスポートファイルのサイズを大幅に削減 できます。Parquetは列指向フォーマットなので、列を絞るほどファイルサイズへの効果は顕著です。

② クエリパフォーマンスの向上

 S3に出力されたParquetファイルをAthenaでクエリするケースでは、ファイルのサイズが小さいほどスキャン量が減り、クエリが速くなり、Athenaのコストも下がります。特に毎日・毎時間更新されるCURを頻繁にクエリする場合、この効果は積み重なります。

③ 関心のあるデータへの絞り込み

 WHERE句を使うことで、特定のサービス・アカウント・リージョンのデータだけをエクスポート することができます。例えば、以下のような絞り込みが可能です。

ユースケース例 WHERE句の例
特定サービスのみ対象 WHERE line_item_product_code = 'AmazonEC2'
税金(Tax)行を除外 WHERE line_item_line_item_type != 'Tax'
特定アカウントのみ WHERE line_item_usage_account_id IN ('111111111111', '222222222222')
特定リージョンのみ WHERE product_region_code = 'ap-northeast-1'

 「EKS関連のコストだけを別のS3パスに出力したい」「開発環境アカウントのデータだけを分析チームに提供したい」といったニーズにも対応できます。

④ データ量の増加を抑制

 AWS環境が大きくなるにつれて、CURのファイルサイズも増大します。SQLクエリによる列・行の絞り込みは、成長するAWS環境においてもデータ量の増加をコントロールする手段 となります。

マネジメントコンソールとCLIでできることの違い

 実は、上で説明したSQLクエリの設定は、マネジメントコンソールからは行えません

 マネジメントコンソールのData Exports設定画面では、エクスポート名・S3の出力先・TIME_GRANULARITY(時間粒度)などの基本的な設定のみが可能で、SQLクエリを直接入力する画面は提供されていません。

 CLIやAPIを利用した場合にのみ使える主な機能を下表にまとめます。

機能 コンソール CLI / API
エクスポートの基本設定(名前・S3出力先など)
TIME_GRANULARITY(HOURLY / DAILY / MONTHLY)
INCLUDE_RESOURCES(リソースIDの含有)
出力カラムをSQLのSELECTで指定
WHERE句による行フィルタリング
INCLUDE_SPLIT_COST_ALLOCATION_DATA 一部
INCLUDE_IAM_PRINCIPAL_DATA

 なお、Data Exportsで利用可能なSQLはフルのSQLではなく、限定されたサブセットです。サポートされている構文は SELECT [columns] FROM [table] WHERE [conditions] の形式で、JOINや集計関数(SUM, COUNTなど)、GROUP BY、ORDER BYはサポートされていません。

手順

手順の全体像

# 内容
1 S3バケットの準備(バケットポリシーの設定)
2 カスタムSQLを設定したData Exportの作成
3 エクスポートの状態確認
4 エクスポート結果の確認

 なお、Data Exportsの作成は us-east-1(バージニア北部)リージョン で行う必要があります(グローバルサービスのため)。

1. S3バケットの準備

バケットの作成

 エクスポート先となるS3バケットを用意します。既存のバケットを流用する場合は次のバケットポリシーの設定へ進んでください。

# 環境変数の設定
ACCOUNT_ID="123456789012"         # ご自身のAWSアカウントID
BUCKET_NAME="cur-custom-${ACCOUNT_ID}"
REGION="ap-northeast-1"           # バケットを作成するリージョン

# バケットの作成
aws s3api create-bucket \
  --bucket ${BUCKET_NAME} \
  --region ${REGION} \
  --create-bucket-configuration LocationConstraint=${REGION}

バケットポリシーの設定

 Data ExportsサービスがS3バケットにファイルを書き込めるよう、バケットポリシーを設定します。

 以下の内容を bucket-policy.json として保存し、適用します。

bucket-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EnableAWSDataExportsToWriteToS3AndCheckPolicy",
      "Effect": "Allow",
      "Principal": {
        "Service": "bcm-data-exports.amazonaws.com"
      },
      "Action": [
        "s3:PutObject",
        "s3:GetBucketPolicy"
      ],
      "Resource": [
        "arn:aws:s3:::YOUR-BUCKET-NAME",
        "arn:aws:s3:::YOUR-BUCKET-NAME/*"
      ],
      "Condition": {
        "StringLike": {
          "aws:SourceArn": "arn:aws:bcm-data-exports:us-east-1:YOUR-ACCOUNT-ID:export/*",
          "aws:SourceAccount": "YOUR-ACCOUNT-ID"
        }
      }
    }
  ]
}
# バケットポリシーの適用
aws s3api put-bucket-policy \
  --bucket ${BUCKET_NAME} \
  --policy file://bucket-policy.json

2. カスタムSQLを設定したData Exportの作成

エクスポート定義ファイルの作成

 以下のJSONファイルを export-definition.json として作成します。このファイルがData Exportの設定の核心部分です。

 今回のサンプルでは、「よく使う主要カラムだけを選択し、Tax(税金)行を除外する」というカスタマイズを行っています。

export-definition.json
{
  "Name": "custom-cur-export",
  "Description": "カスタムSQL付きCUR 2.0エクスポート",
  "DataQuery": {
    "QueryStatement": "SELECT identity_line_item_id, identity_time_interval, bill_payer_account_id, bill_billing_period_start_date, bill_billing_period_end_date, line_item_usage_account_id, line_item_usage_account_name, line_item_line_item_type, line_item_usage_start_date, line_item_usage_end_date, line_item_product_code, line_item_usage_type, line_item_operation, line_item_availability_zone, line_item_usage_amount, line_item_unblended_cost, line_item_blended_cost, line_item_line_item_description, product_region_code, product_instance_type, product_product_family, pricing_term, pricing_unit, reservation_reservation_a_r_n, reservation_effective_cost, savings_plan_savings_plan_a_r_n, savings_plan_savings_plan_effective_cost, resource_tags, cost_category FROM COST_AND_USAGE_REPORT WHERE line_item_line_item_type != 'Tax'",
    "TableConfigurations": {
      "COST_AND_USAGE_REPORT": {
        "TIME_GRANULARITY": "DAILY",
        "INCLUDE_RESOURCES": "TRUE",
        "INCLUDE_SPLIT_COST_ALLOCATION_DATA": "FALSE",
        "INCLUDE_MANUAL_DISCOUNT_COMPATIBILITY": "FALSE"
      }
    }
  },
  "DestinationConfigurations": {
    "S3Destination": {
      "S3Bucket": "YOUR-BUCKET-NAME",
      "S3Prefix": "cur-custom",
      "S3Region": "ap-northeast-1",
      "S3OutputConfigurations": {
        "OutputType": "CUSTOM",
        "Format": "PARQUET",
        "Compression": "PARQUET",
        "Overwrite": "OVERWRITE_REPORT"
      }
    }
  },
  "RefreshCadence": {
    "Frequency": "SYNCHRONOUS"
  }
}

 主要な設定項目を説明します。

DataQuery.QueryStatement

 ここにSQLクエリを記載します。SELECTで出力するカラムを指定し、FROMにテーブル名(COST_AND_USAGE_REPORT)を指定します。行を絞り込む場合はWHERE句を追記します。

 利用可能なカラム一覧は、以下のCLIコマンドで確認できます。

aws bcm-data-exports get-table \
  --table-name COST_AND_USAGE_REPORT \
  --region us-east-1 \
  --query 'Schema[*].Name' \
  --output text

DataQuery.TableConfigurations

 QueryStatementに加え、テーブル固有のオプションを設定します。COST_AND_USAGE_REPORTで利用できる主なオプションは以下の通りです。

プロパティ名 説明 指定可能値 デフォルト
TIME_GRANULARITY データの時間粒度 HOURLY / DAILY / MONTHLY HOURLY
INCLUDE_RESOURCES リソースIDをレポートに含めるか TRUE / FALSE FALSE
INCLUDE_SPLIT_COST_ALLOCATION_DATA Split Cost Allocationデータを含めるか TRUE / FALSE FALSE
INCLUDE_MANUAL_DISCOUNT_COMPATIBILITY 手動割引の互換データを含めるか TRUE / FALSE FALSE
INCLUDE_IAM_PRINCIPAL_DATA IAMプリンシパルのカラムを含めるか TRUE / FALSE -

S3OutputConfigurations

設定 今回の選択 説明
Format PARQUET 出力フォーマット(PARQUET または TEXT_OR_CSV
Compression PARQUET 圧縮形式(PARQUET形式の場合はPARQUET固定)
OutputType CUSTOM SQLクエリを使う場合はCUSTOMを指定する
Overwrite OVERWRITE_REPORT 同一期間のデータを上書きするか

 OutputTypeは必ずCUSTOMを指定してください。 OutputTypeに指定できる値はCUSTOMのみです。

 また、Overwriteフィールドについても注意が必要です。CREATE_NEW_REPORTを指定すると更新のたびに新規ファイルが追記されデータが重複するため、基本的にはOVERWRITE_REPORT(同一期間のデータを上書き)を推奨します。

create-exportコマンドの実行

aws bcm-data-exports create-export \
  --export file://export-definition.json \
  --region us-east-1

実行結果の例:

{
    "ExportArn": "arn:aws:bcm-data-exports:us-east-1:123456789012:export/custom-cur-export-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

 返却されたExportArnは次のステップで使用するので控えておきます。

3. エクスポートの状態確認

エクスポートの設定内容の確認

 作成したエクスポートの設定が正しく反映されているか確認します。

EXPORT_ARN="arn:aws:bcm-data-exports:us-east-1:123456789012:export/custom-cur-export-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

aws bcm-data-exports get-export \
  --export-arn ${EXPORT_ARN} \
  --region us-east-1 \
  --no-cli-pager

DataQuery.QueryStatementに設定したSQLが正しく反映されていることを確認します。

エクスポート実行履歴の確認

 Data Exportsの実行(Execution)状況は以下で確認できます。

aws bcm-data-exports list-executions \
  --export-arn ${EXPORT_ARN} \
  --region us-east-1

ExecutionStatus.StatusCodeSUCCESSになっていれば、S3へのエクスポートが完了しています。

ステータスコードの意味は以下の通りです。

StatusCode 説明
QUEUED キューに入っている
IN_PROGRESS 実行中
SUCCESS 正常完了
FAILED 失敗

4. エクスポート結果の確認

 S3バケットに出力されたParquetファイルを確認します。

# エクスポートされたファイルの確認
aws s3 ls s3://${BUCKET_NAME}/cur-custom/ --recursive

 出力されたParquetファイルは、Athenaから直接クエリすることもできます。S3のバケットとプレフィックスをAthena外部テーブルとして登録するか、AWS Glue Crawlerで自動的にスキーマを検出させることで、Athena上でSQLクエリを実行できます。

 エクスポートされたファイルに指定したカラムのみが含まれていること、WHERE句の条件が反映されていることを確認しましょう。

補足:既存のエクスポートをSQLクエリ付きに更新したい場合

 マネジメントコンソールで作成した既存のエクスポートにSQLクエリを追加したい場合は、update-exportコマンドを使います。

aws bcm-data-exports update-export \
  --export-arn ${EXPORT_ARN} \
  --export file://export-definition.json \
  --region us-east-1

 ただし、OutputTypeCREATE_NEW_REPORTからCUSTOMに変更する更新はサポートされていません。その場合は、CUSTOMを指定した新規エクスポートを作り直す必要があります。

まとめ

 本記事では、AWS BCM Data ExportsのCUR 2.0に対して、CLIを利用してSQLクエリを設定する方法を紹介しました。

 マネジメントコンソールからは設定できないSQLクエリ機能を活用することで、以下のメリットが得られます。

  • S3ストレージコストの削減: 不要なカラムを除外し、エクスポートファイルのサイズを削減
  • Athenaクエリの高速化・コスト削減: スキャン量が減ることでクエリが速くなりコストも下がる
  • 関心データへの絞り込み: WHERE句で特定サービス・アカウントのデータだけをエクスポート

 CURをそのまま使うのも一つの選択ですが、扱うデータ量が増えてきたり、コスト分析の用途が明確になってきたりしたタイミングでカスタマイズを検討してみてはいかがでしょうか。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?