【メンバーズ新機能】メンバーズ組織CURで複数AWSアカウントのコスト分析を簡単に!Athenaによる実践ガイド

【メンバーズ新機能】メンバーズ組織CURで複数AWSアカウントのコスト分析を簡単に!Athenaによる実践ガイド

2025年2月リリースの「メンバーズ組織CUR」で複数AWSアカウントのコスト分析が簡素化されました。 本記事では、Amazon Athenaでコスト分析するための2つの方法(AWS Glue活用法とPartition Projection活用法)を比較しながら、実装手順を詳しく解説します。
Clock Icon2025.02.28

はじめに

AWSでは、AWSサービスの利用明細が記載された Cost and Usage Report(CUR)を取得できます。
弊社のAWS総合支援サービスである「クラスメソッドメンバーズ」でも、AWSのレガシーCUR仕様に準拠した メンバーズCUR を提供しています。

このメンバーズCURは個別のAWSアカウント単位でのみ設定・出力が可能で、複数アカウントを跨いだコスト分析には次の手順が必要でした。

  1. 分析したい各アカウントで個別にメンバーズCUR出力設定
  2. 各アカウントに出力されたメンバーズCURを単一アカウントへコピーして集約
  3. 集約したデータをAthena等で分析

しかし上記手順は環境構築の方法が複雑で、お客様からは「もっとシンプルに複数のアカウントを跨いだコスト分析を行いたい」というご要望をいただいていました。

そしてこの度、2025年2月13日に メンバーズ組織CUR がリリースされました!🎉 🎉 🎉

クラスメソッドメンバーズでは、複数のアカウントを「メンバーズ組織」という単位で管理しています。
メンバーズ組織CURでは、この「メンバーズ組織」内の全アカウントのコスト情報をまとめて出力でき、アカウントを跨いだコスト分析環境の構築が大幅に簡素化されました。

既存のメンバーズCUR メンバーズ組織CUR
出力先 指定したAWSアカウントのS3バケット 指定したAWSアカウントのS3バケット
出力される情報 出力先AWSアカウントのみの情報 メンバーズ組織内の全AWSアカウントの情報

既存のメンバーズCURとメンバーズ組織CURの比較

本記事では、このメンバーズ組織CURをAmazon Athenaで分析する方法を2つ紹介します。

  1. AWS Glueを使った方法
  2. AthenaのPartition Projectionを使った方法

メンバーズ組織CURの出力フォーマットはParquetとCSVに対応していますが、今回はAthenaでの分析に適しているParquetを前提に説明します。

前提条件

Athenaで分析するメンバーズ組織CURの出力設定例を下記とします。

フォーマット S3バケット S3パスプレフィックス エクスポート名
Parquet cm-cur-123456789012 cur/classmethod org-cur-parquet

このように設定すると、指定のS3バケットにメンバーズ組織CURが出力されます。
出力は概ね一日2回行われます。即時出力ではないのでご注意ください。

下記は2025年1月から3月まで出力した場合のファイル構成の例です。

cm-cur-123456789012/
   └ cur/
      └ classmethod/
         └ org-cur-parquet/
            ├ org-cur-parquet/
            │  └ year=2025/
            │     ├ month=1/
            │     │  ├ org-cur-parquet-00001.snappy.parquet
            │     │  ├ org-cur-parquet-00002.snappy.parquet
            │     │  └ org-cur-parquet-00003.snappy.parquet
            │     ├ month=2/
            │     │  ├ org-cur-parquet-00001.snappy.parquet
            │     │  ├ org-cur-parquet-00002.snappy.parquet
            │     │  └ org-cur-parquet-00003.snappy.parquet
            │     └ month=3/
            │        ├ org-cur-parquet-00001.snappy.parquet
            │        ├ org-cur-parquet-00002.snappy.parquet
            │        └ org-cur-parquet-00003.snappy.parquet
            ├ 20250101-20250201/
            │  └ org-cur-parquet-Manifest.json
            ├ 20250201-20250301/
            │  └ org-cur-parquet-Manifest.json
            └ 20250301-20250401/
               └ org-cur-parquet-Manifest.json

AWSの上書きの仕様と同様に、同月内で新しいファイルが出力されると古いファイルは上書きされます。
https://docs.aws.amazon.com/ja_jp/cur/latest/userguide/understanding-report-versions.html#overwrite-previous-cur

方法1: AWS Glueを使った方法

アーキテクチャ概要

Glueを使った方法
各リソースの説明は次の通りです。

リソース名 説明
S3 Bucket
cm-cur-123456789012
メンバーズ組織CURが出力されるS3バケット
Glue Crawler
members-cur-crawler
cm-cur-123456789012バケットを定期的にクロールするCrawler
Glue Data Catalog
members-cur
Crawlerによって作成されたメタデータが保存されるデータカタログ
Amazon Athena CURを分析するAthena

この環境を構築していきます。

構築手順

AWS Glue Crawlerを利用して、cm-cur-123456789012バケットに出力されたメンバーズ組織CURを分析するためのリソースを作成します。

環境構築用のCloudFormationテンプレートは次の通りです。

CloudFormationテンプレート(YAML)
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CFn template that sets up AWS Glue Crawler to analyze Classmethod Members CUR'

Parameters:
  S3BucketName:
    Type: String
    Description: 'S3 Bucket Name (ex. cm-cur-123456789012)'

  S3PathPrefix:
    Type: String
    Description: 'S3 Path Prefix (ex. cur/classmethod)'

Resources:
  MembersCurDatabase:
    Type: AWS::Glue::Database
    Properties:
      CatalogId: !Ref AWS::AccountId
      DatabaseInput:
        Name: 'members-cur'
        Description: 'Database for Classmethod Members CUR'

  GlueServiceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: 'AWSGlueServiceRole-MembersCur'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: glue.amazonaws.com
            Action: 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole'

  GlueServiceRoleS3Policy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: S3Access
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - 's3:GetObject'
              - 's3:PutObject'
            Resource:
              - !Sub 'arn:aws:s3:::${S3BucketName}/${S3PathPrefix}/*'
      Roles:
        - !Ref GlueServiceRole

  MembersCurCrawler:
    Type: AWS::Glue::Crawler
    DependsOn:
      - MembersCurDatabase
      - GlueServiceRole
    Properties:
      Name: 'members-cur-crawler'
      Description: 'Classmethod Members CUR crawler'
      Role: !GetAtt GlueServiceRole.Arn
      DatabaseName: 'members-cur'
      Targets:
        S3Targets:
          - Path: !Sub
              - 's3://${S3BucketName}/${FirstPathComponent}'
              - FirstPathComponent: !Select [0, !Split ["/", !Ref S3PathPrefix]]
            Exclusions:
              - '**.json'
      Schedule:
        ScheduleExpression: 'cron(0 0 * * ? *)'
      RecrawlPolicy:
        RecrawlBehavior: 'CRAWL_NEW_FOLDERS_ONLY'
      SchemaChangePolicy:
        UpdateBehavior: 'LOG'
        DeleteBehavior: 'LOG'

Outputs:
  GlueDatabase:
    Description: 'The Glue Database name'
    Value: 'members-cur'

  GlueCrawler:
    Description: 'The Glue Crawler name'
    Value: 'members-cur-crawler'

  GlueServiceRoleArn:
    Description: 'The ARN of the IAM role for Glue service'
    Value: !GetAtt GlueServiceRole.Arn

  CrawlerTargetPath:
    Description: 'The actual S3 path being crawled'
    Value: !Sub
      - 's3://${S3BucketName}/${FirstPathComponent}'
      - FirstPathComponent: !Select [0, !Split ["/", !Ref S3PathPrefix]]

テンプレートからスタックを作成する際に下記パラメータの入力が求められるので、ご自身の設定した値を入力してください。

  • S3BucketName: 設定したS3バケット名
  • S3PathPrefix: 設定したS3パスプレフィックス

AWS CLIで構築する場合は以下の手順を実行してください。
CLIは下記バージョンを使用しています。

aws-cli/2.24.11 Python/3.12.9 Darwin/24.3.0 source/arm64

ステップ1: Glueデータベースの作成

aws glue create-database \
    --database-input '{
        "Name": "members-cur",
        "Description": "Database for Classmethod Members CUR"
    }'

ステップ2: Glueクローラ用IAMロールの作成

aws iam create-role \
    --role-name AWSGlueServiceRole-MembersCur \
    --assume-role-policy-document '{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Service": "glue.amazonaws.com"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }'

ステップ3: IAMロールにAWS管理ポリシーをアタッチ

aws iam attach-role-policy \
    --role-name AWSGlueServiceRole-MembersCur \
    --policy-arn arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole

ステップ4: IAMロールにS3アクセス権限を追加

aws iam put-role-policy \
    --role-name AWSGlueServiceRole-MembersCur \
    --policy-name S3Access \
    --policy-document '{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject",
                    "s3:PutObject"
                ],
                "Resource": [
                    "arn:aws:s3:::cm-cur-123456789012/cur/classmethod/*"
                ]
            }
        ]
    }'

ステップ5: Glueクローラの作成

schedule は毎日0時に実行されるようにしています。
一時的な利用であれば schedule の指定を行ごと削除してオンデマンド実行にしてください。

aws glue create-crawler \
    --name members-cur-crawler \
    --description "Classmethod Members CUR crawler" \
    --role "AWSGlueServiceRole-MembersCur" \
    --targets '{
        "S3Targets": [
            {
                "Path": "s3://cm-cur-123456789012/cur/",
                "Exclusions": ["**.json"]
            }
        ]
    }' \
    --database-name members-cur \
    --schedule "cron(0 0 * * ? *)" \
    --recrawl-policy "RecrawlBehavior=CRAWL_NEW_FOLDERS_ONLY" \
    --schema-change-policy '{
        "UpdateBehavior": "LOG",
        "DeleteBehavior": "LOG"
    }'

以上で全ての設定は完了です。
クローラの定期実行により、cm-cur-123456789012バケットに出力されたメンバーズ組織CURのメタデータが毎日登録されます。

方法2: AthenaのPartition Projectionを使った方法

Glueを使わずにAthenaのPartition Projection機能を活用する、よりシンプルな方法です。
Glueを使った方法と、AthenaのPartition Projectionを使った方法との比較は後述します。

Partition Projectionについては、下記のエントリ等を参照してください。
https://dev.classmethod.jp/articles/20200627-amazon-athena-partition-projection/

アーキテクチャ概要

AthenaのPartition Projectionを使った方法

構築手順

ステップ1: Athenaデータベースの作成

Athenaで以下のDDLを実行してください。

CREATE DATABASE `members-cur`;

ステップ2: テーブルの作成

作成したデータベースで以下のDDLを実行してください。

DDL(長いため折りたたみます)
CREATE EXTERNAL TABLE `cur` (
  `identity_line_item_id` string, 
  `identity_time_interval` string, 
  `bill_invoice_id` string, 
  `bill_billing_entity` string, 
  `bill_bill_type` string, 
  `bill_payer_account_id` string, 
  `bill_billing_period_start_date` timestamp, 
  `bill_billing_period_end_date` timestamp, 
  `bill_invoicing_entity` string, 
  `line_item_usage_account_id` string, 
  `line_item_line_item_type` string, 
  `line_item_usage_start_date` timestamp, 
  `line_item_usage_end_date` timestamp, 
  `line_item_product_code` string, 
  `line_item_usage_type` string, 
  `line_item_operation` string, 
  `line_item_availability_zone` string, 
  `line_item_resource_id` string, 
  `line_item_usage_amount` double, 
  `line_item_normalization_factor` double, 
  `line_item_normalized_usage_amount` double, 
  `line_item_currency_code` string, 
  `line_item_unblended_rate` string, 
  `line_item_unblended_cost` double, 
  `line_item_line_item_description` string, 
  `line_item_tax_type` string, 
  `line_item_legal_entity` string, 
  `product_product_name` string, 
  `product_accelerator_size` string, 
  `product_accelerator_type` string, 
  `product_access_type` string, 
  `product_activity_type` string, 
  `product_addon_feature` string, 
  `product_alarm_type` string, 
  `product_api_type` string, 
  `product_attachment_type` string, 
  `product_availability` string, 
  `product_availability_zone` string, 
  `product_bit_rate` string, 
  `product_broker_engine` string, 
  `product_bundle` string, 
  `product_cache_engine` string, 
  `product_cache_memory_size_gb` string, 
  `product_calling_type` string, 
  `product_capacitystatus` string, 
  `product_category` string, 
  `product_client_location` string, 
  `product_clock_speed` string, 
  `product_cloud_search_version` string, 
  `product_codec` string, 
  `product_compute_family` string, 
  `product_compute_type` string, 
  `product_concurrencyscalingfreeusage` string, 
  `product_content_type` string, 
  `product_country` string, 
  `product_counts_against_quota` string, 
  `product_cputype` string, 
  `product_current_generation` string, 
  `product_data` string, 
  `product_data_transfer` string, 
  `product_data_transfer_quota` string, 
  `product_database_edition` string, 
  `product_database_engine` string, 
  `product_datatransferout` string, 
  `product_dedicated_ebs_throughput` string, 
  `product_deployment_location` string, 
  `product_deployment_option` string, 
  `product_describes` string, 
  `product_description` string, 
  `product_device` string, 
  `product_device_type` string, 
  `product_direct_connect_location` string, 
  `product_directory_size` string, 
  `product_directory_type` string, 
  `product_directory_type_description` string, 
  `product_dominantnondominant` string, 
  `product_durability` string, 
  `product_ebs_optimized` string, 
  `product_ecu` string, 
  `product_edition` string, 
  `product_elastic_graphics_type` string, 
  `product_endpoint` string, 
  `product_endpoint_type` string, 
  `product_engine` string, 
  `product_engine_code` string, 
  `product_enhanced_networking_support` string, 
  `product_enhanced_networking_supported` string, 
  `product_entity_type` string, 
  `product_event_type` string, 
  `product_execution_frequency` string, 
  `product_execution_location` string, 
  `product_fee_code` string, 
  `product_fee_description` string, 
  `product_file_system_type` string, 
  `product_frame_rate` string, 
  `product_free_overage` string, 
  `product_free_query_types` string, 
  `product_free_tier` string, 
  `product_free_trial` string, 
  `product_free_usage_included` string, 
  `product_frequency_mode` string, 
  `product_from_location` string, 
  `product_from_location_type` string, 
  `product_georegioncode` string, 
  `product_gets` string, 
  `product_gpu` string, 
  `product_gpu_memory` string, 
  `product_graphqloperation` string, 
  `product_group` string, 
  `product_group_description` string, 
  `product_high_availability` string, 
  `product_indexing_source` string, 
  `product_ingest_type` string, 
  `product_input` string, 
  `product_input_mode` string, 
  `product_instance` string, 
  `product_instance_capacity10xlarge` string, 
  `product_instance_capacity12xlarge` string, 
  `product_instance_capacity24xlarge` string, 
  `product_instance_capacity2xlarge` string, 
  `product_instance_capacity4xlarge` string, 
  `product_instance_capacity8xlarge` string, 
  `product_instance_capacity_large` string, 
  `product_instance_capacity_xlarge` string, 
  `product_instance_family` string, 
  `product_instance_function` string, 
  `product_instance_type` string, 
  `product_instance_type_family` string, 
  `product_instances` string, 
  `product_instancesku` string, 
  `product_intel_avx2_available` string, 
  `product_intel_avx_available` string, 
  `product_intel_turbo_available` string, 
  `product_io` string, 
  `product_license` string, 
  `product_license_model` string, 
  `product_license_type` string, 
  `product_line_type` string, 
  `product_location` string, 
  `product_location_type` string, 
  `product_logs_source` string, 
  `product_logs_type` string, 
  `product_machine_learning_process` string, 
  `product_mailbox_storage` string, 
  `product_max_iops_burst_performance` string, 
  `product_max_iopsvolume` string, 
  `product_max_throughputvolume` string, 
  `product_max_volume_size` string, 
  `product_maximum_capacity` string, 
  `product_maximum_extended_storage` string, 
  `product_maximum_storage_volume` string, 
  `product_memory` string, 
  `product_memory_gib` string, 
  `product_memorytype` string, 
  `product_message_delivery_frequency` string, 
  `product_message_delivery_order` string, 
  `product_metering_type` string, 
  `product_min_volume_size` string, 
  `product_minimum_storage_volume` string, 
  `product_network_performance` string, 
  `product_newcode` string, 
  `product_normalization_size_factor` string, 
  `product_offer` string, 
  `product_operating_system` string, 
  `product_operation` string, 
  `product_operation_type` string, 
  `product_ops_items` string, 
  `product_origin` string, 
  `product_os_license_model` string, 
  `product_output` string, 
  `product_output_mode` string, 
  `product_overage_type` string, 
  `product_parameter_type` string, 
  `product_physical_cores` string, 
  `product_physical_cpu` string, 
  `product_physical_gpu` string, 
  `product_physical_processor` string, 
  `product_pipeline` string, 
  `product_port_speed` string, 
  `product_pre_installed_sw` string, 
  `product_processor_architecture` string, 
  `product_processor_features` string, 
  `product_product_family` string, 
  `product_protocol` string, 
  `product_provisioned` string, 
  `product_queue_type` string, 
  `product_readtype` string, 
  `product_realtimeoperation` string, 
  `product_recipient` string, 
  `product_region` string, 
  `product_request_description` string, 
  `product_request_type` string, 
  `product_resolution` string, 
  `product_resource_endpoint` string, 
  `product_resource_type` string, 
  `product_rootvolume` string, 
  `product_routing_target` string, 
  `product_routing_type` string, 
  `product_running_mode` string, 
  `product_servicecode` string, 
  `product_servicename` string, 
  `product_single_or_dual_pass` string, 
  `product_sku` string, 
  `product_software_included` string, 
  `product_software_type` string, 
  `product_standard_storage_retention_included` string, 
  `product_steps` string, 
  `product_storage` string, 
  `product_storage_class` string, 
  `product_storage_description` string, 
  `product_storage_media` string, 
  `product_storage_type` string, 
  `product_subscription_type` string, 
  `product_supported_modes` string, 
  `product_tenancy` string, 
  `product_tenancy_support` string, 
  `product_throughput` string, 
  `product_throughput_class` string, 
  `product_tier` string, 
  `product_tiertype` string, 
  `product_to_location` string, 
  `product_to_location_type` string, 
  `product_traffic_direction` string, 
  `product_transcoding_result` string, 
  `product_transfer_type` string, 
  `product_type` string, 
  `product_updates` string, 
  `product_usage_family` string, 
  `product_usagetype` string, 
  `product_uservolume` string, 
  `product_vcpu` string, 
  `product_version` string, 
  `product_video_codec` string, 
  `product_video_frame_rate` string, 
  `product_video_memory_gib` string, 
  `product_video_quality` string, 
  `product_video_quality_setting` string, 
  `product_video_resolution` string, 
  `product_virtual_interface_type` string, 
  `product_volume_api_name` string, 
  `product_volume_type` string, 
  `product_vq_setting` string, 
  `pricing_lease_contract_length` string, 
  `pricing_offering_class` string, 
  `pricing_purchase_option` string, 
  `pricing_public_on_demand_cost` double, 
  `pricing_public_on_demand_rate` string, 
  `pricing_term` string, 
  `pricing_unit` string, 
  `reservation_amortized_upfront_cost_for_usage` double, 
  `reservation_amortized_upfront_fee_for_billing_period` double, 
  `reservation_availability_zone` string, 
  `reservation_effective_cost` double, 
  `reservation_end_time` string, 
  `reservation_modification_status` string, 
  `reservation_normalized_units_per_reservation` string, 
  `reservation_number_of_reservations` string, 
  `reservation_recurring_fee_for_usage` double, 
  `reservation_reservation_a_r_n` string, 
  `reservation_start_time` string, 
  `reservation_total_reserved_normalized_units` string, 
  `reservation_total_reserved_units` string, 
  `reservation_units_per_reservation` string, 
  `reservation_unused_amortized_upfront_fee_for_billing_period` double, 
  `reservation_unused_normalized_unit_quantity` double, 
  `reservation_unused_quantity` double, 
  `reservation_unused_recurring_fee` double, 
  `reservation_upfront_value` double, 
  `resource_tags_user_cm_billing_group` string, 
  `savings_plan_total_commitment_to_date` double, 
  `savings_plan_savings_plan_a_r_n` string, 
  `savings_plan_savings_plan_rate` double, 
  `savings_plan_used_commitment` double, 
  `savings_plan_savings_plan_effective_cost` double, 
  `savings_plan_amortized_upfront_commitment_for_billing_period` double, 
  `savings_plan_recurring_commitment_for_billing_period` double, 
  `savings_plan_region` string, 
  `savings_plan_payment_option` string, 
  `savings_plan_end_time` string, 
  `savings_plan_instance_type_family` string, 
  `savings_plan_purchase_term` string, 
  `savings_plan_offering_type` string, 
  `savings_plan_start_time` string
)
PARTITIONED BY (
  `year` string, 
  `month` string
)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  's3://cm-cur-123456789012/cur/'
TBLPROPERTIES (
  'partition_filtering.enabled'='true',
  'projection.enabled'='true',
  'projection.year.type'='date',
  'projection.year.range'='2025,NOW+9HOURS',
  'projection.year.format'='yyyy',
  'projection.year.interval'='1',
  'projection.year.interval.unit'='YEARS',
  'projection.month.type'='integer',
  'projection.month.range'='1,12',
  'projection.month.format'='%d',
  'storage.location.template'='s3://cm-cur-123456789012/cur/classmethod/org-cur-parquet/org-cur-parquet/year=${year}/month=${month}'
);

2つの方法の比較

Glueを使った方法と、AthenaのPartition Projectionを使った方法を比較します。
ご自身の環境により使い分けてください。

Glueを使った方法 Partition Projectionを使った方法
環境構築の複雑さ 複雑(複数リソースの設定が必要) シンプル(SQLクエリのみ)
クエリのパフォーマンス [1] 高い 条件によって低下の可能性あり
汎用性 [2] 高い(Redshift、EMRなどと連係可能) 低い(Athenaのみ対応)

Athenaでの分析

これまでの設定でメンバーズ組織CURをAthenaで分析可能になります。
CURの各カラムについてはAWSのドキュメントをご確認ください。
https://docs.aws.amazon.com/ja_jp/cur/latest/userguide/data-dictionary.html

クエリサンプル

Athenaの環境構築が完了したことを確認するためクエリを実行してみます。
例として、メンバーズポータルで表示される料金を確認します。

WITH "categorized_billing" AS (
  SELECT
    "year",
    "month",
    "line_item_usage_account_id",
    CASE
      WHEN "line_item_line_item_type" = 'Fee' THEN '前払料金'
      WHEN "line_item_line_item_type" IN ('RIFee', 'SavingsPlanRecurringFee') THEN '毎月料金'
      WHEN "bill_billing_entity" = 'AWS Marketplace' THEN 'マーケットプレイス料金'
      WHEN "bill_billing_entity" = 'CM' AND "product_product_name" = 'Classmethod Members Discount' THEN 'メンバーズ割引'
      ELSE '通常利用料金'
    END AS "category",
    "line_item_unblended_cost"
  FROM "members-cur"."cur"
  WHERE "line_item_usage_account_id" IN (
    '123456789012' -- 分析したいアカウントのID
  )
)

SELECT
  "year" AS "年",
  "month" AS "月",
  "line_item_usage_account_id" AS "AWSアカウントID",
  "category" AS "料金カテゴリ",
  SUM("line_item_unblended_cost") AS "金額"
FROM "categorized_billing"
WHERE "year" = '2025'
AND "month" = '2'
GROUP BY
  "year",
  "month",
  "line_item_usage_account_id",
  "category"
ORDER BY
  "year",
  "month",
  "line_item_usage_account_id",
  "category";

このクエリを実行すると、メンバーズポータルに表示されている金額と一致することを確認できます。

まとめ

メンバーズ組織CURを活用することで、複数アカウントのコスト情報を一元管理・分析できるようになりました。
本記事で紹介した2つの方法から、ご自身の環境に合った方法を選択して実装してください。

  • Glueを使った方法: 他のAWSサービスとの連携が必要な場合に最適
  • Partition Projectionを使った方法: シンプルな環境で素早く始めたい場合に最適

詳細なコスト分析を通じて、AWSリソースの最適化にお役立てください!

脚注
  1. Partition Projectionでは、クエリ実行時のWHERE句でパーティションを指定せずにフルスキャンした場合、設定した全てのパーティションを読みにいってパフォーマンスが低下する可能性があります。
    projection.date.range の指定には注意してください。
    下記エントリが参考になります。
    https://dev.classmethod.jp/articles/partition-projection-shikujiri-s3-cost-increase/ ↩︎

  2. Partition ProjectionはAthenaのクエリエンジンのみサポートする機能なので、別のクエリエンジンではデータが参照できません。Redshift Spectrum、Glue、EMRなど、別のサービスを通じて同じテーブルを参照する場合はパーティションが登録されていないため利用できません。 ↩︎

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.