Amazon Web Services ブログ

AWS Glue および Amazon Redshift を使用して Amazon S3 の利用料金を分析する

AWS のコストと使用状況レポート (CUR) は、AWS の使用状況を追跡し、それに関連する推定請求額を算出します。このレポートは、毎時または日次ベースのデータを表示するように設定することができます。レポートは請求確定日までに、1 日に少なくとも 1 回更新されます。コストと使用状況レポートは、指定する Amazon S3 バケットに自動的に配信され、そこから直接ダウンロードできます。また、このレポートは、Amazon Redshift に統合したり、Amazon Athena でクエリを実行したり、Amazon QuickSight にアップロードしたりすることができます。詳細については、Query and Visualize AWS Cost and Usage Data Using Amazon Athena and Amazon QuickSight を参照してください。

この投稿では、AWS CUR、S3 インベントリレポート、S3 サーバーアクセスログを組み合わせることにより、AWS Glue データカタログと Amazon Redshift を使用して S3 の使用状況と利用料金を分析するソリューションを提供します。

前提条件

開始する前に、次の前提条件を満たしてください。

  • S3 インベントリとサーバーアクセスログデータファイル用に、S3 バケットが必要です。詳細については、「バケットの作成」と「Amazon S3 とは」を参照してください。
  • Amazon Redshift が S3 バケットにアクセスできるようにするには、適切な IAM アクセス許可が必要です。この投稿では、制限のない 2 つの IAM ロール (AmazonS3FullAccess および AWSGlueConsoleFullAccess) を選択しますが、自分のシナリオに合わせてアクセスの制限をしてください。

Amazon S3 インベントリ

Amazon S3 インベントリは、ストレージ管理を支援するために S3 が提供するツールの 1 つです。このツールを、オブジェクトのレプリケーションおよび暗号化のステータスを監査およびレポートするために使用することで、ビジネス、コンプライアンス、規制のニーズに応えることができます。Amazon S3 インベントリは、S3 バケットに関して、オブジェクトとそれに対応するメタデータをリスト化したカンマ区切り値 (CSV)、Apache の ORC (Optimized Row Columnar)、Apache Parquet の出力ファイルを日次または週次ベースで提供します。

Amazon S3 サーバーアクセスログ

サーバーアクセスログ記録は、バケットに対して行われたリクエストの詳細な記録を提供します。サーバーアクセスログは、セキュリティやアクセスの監査など、多くのアプリケーションで役に立ちます。また、顧客基盤を知り、S3 の請求を理解することにも役立ちます。

AWS Glue

AWS Glue はフルマネージド型のデータ抽出、変換、ロード (ETL) サービスです。このサービスを使用すれば、データに対する分類、クリーニング、エンリッチ化に加え、データストア間での確実なデータ移行が行えます。AWS Glue は、データカタログと呼ばれる中央メタデータリポジトリ、データカタログにテーブルを追加するクローラー、Python または Scala コードを自動的に生成する ETL エンジン、および依存関係の解決、ジョブのモニタリング、再試行を処理する柔軟なスケジューラで構成されています。AWS Glue はサーバーレスであるため、設定や管理が必要なインフラストラクチャはありません。この投稿では、AWS Glue を使用して S3 インベントリデータおよびサーバーアクセスログのカタログを作成します。 これにより、Amazon Redshift Spectrum を使ってクエリを実行できます。

Amazon Redshift

Amazon Redshiftは、クラウド上の、フルマネージド型でペタバイト規模のデータウェアハウスサービスです。Amazon Redshift を使用すると、効率的にクエリを実行し、Amazon Redshift のネイティブテーブルにデータをロードすることなく、S3 のファイルから構造化データまたは半構造化データを取得することができます。Amazon Redshift の外部テーブルを作成するには、ファイルの構造を定義し、それらを AWS Glue データカタログにテーブルとして登録します。

S3 インベントリの分析レポートの設定

この投稿では、インベントリレポートに Parquet ファイル形式を使用して、ファイルを毎日 S3 バケットに配信します。配信の頻度および出力ファイルのフォーマットは、下のスクリーンショットのように [Advanced settings] で選択できます。

S3 インベントリの設定の詳細については、「Amazon S3 インベントリを設定する方法」を参照してください。

次の図は、このソリューションのデータフローを示しています。

次の手順は、上で説明されたデータフロー図を要約したものです。

  • S3 インベントリレポートは、設定した S3 バケットに配信されます。
  • その後、AWS Glue クローラーがこの S3 バケットをクロールし、AWS Glue データカタログにメタデータを投入します。
  • それにより、AWS Glue データカタログに Redshift の外部スキーマを介してアクセスすることができます。
  • S3 インベントリレポート (AWS Glue データカタログで利用可能) およびコストと使用状況レポート (別の S3 バケットで利用可能) で、分析への参加およびクエリの準備ができています。

インベントリレポートは、S3 バケットに配信されます。次のスクリーンショットは、S3 インベントリレポートの S3 バケット構造を示しています。

このバケットにはデータフォルダがあります。このフォルダには分析する Parquet データが含まれています。次のスクリーンショットはフォルダのコンテンツを示しています。

これらは日次ファイルなので、1 日あたり 1 つのファイルがあります。

AWS Glue クローラを設定する

AWS Glue クローラを使用して、S3 バケット内でこのデータセットを発見したり、データカタログ内でテーブルスキーマを作成したりできます。こうしたテーブルを作成した後に、Amazon Redshift から直接クエリできます。

S3 バケットから S3 インベントリファイルを読み込むようクローラを設定するには、以下のステップを実行します。

  1. クローラ名を選択します。
  2. データストアに S3 を選択し、そのデータ用の S3 パスを指定します。
  3. S3 からデータを読み込む IAM ロール、AmazonS3FullAccess および AWSGlueConsoleFullAccess を選択します。
  4. クローラを実行する頻度スケジュールを設定します。
  5. データベースを選択し、プレフィックスがある場合は追加して、クローラの出力を設定します。

この投稿では s3spendanalysis というデータベースを使用します。

次のスクリーンショットは、完了したクローラの設定を示しています。

このクローラを実行して Glue データカタログにテーブルを追加します。クローラが正常に完了したら、AWS Glue コンソールで [Tables] セクションに進み、テーブルの詳細およびテーブルのメタデータを検証します。次のスクリーンショットは、AWS Glue クローラが正常に完了した後のテーブルの詳細およびテーブルのメタデータを示しています。

外部スキーマを作成する

S3 インベントリレポートをクエリする前に、Amazon Redshift で外部スキーマを作成 (続いて外部テーブルを作成) する必要があります。Amazon Redshift 外部スキーマは、外部データカタログ内の外部データベースを参照します。外部カタログとして AWS Glue Data Catalog を使用しているため、Amazon Redshift で外部スキーマを作成後、Amazon Redshift 内の Data Catalog で外部テーブルの全てを表示することができます。外部スキーマを作成するには、以下のコードを入力します。

create external schema spectrum_schema from data catalog
database 's3spendanalysis'
iam_role 'arn:aws:iam::<AWS_IAM_ROLE>';

テーブルをクエリする

Amazon Redshift ダッシュボードでは、データテーブルをクエリエディタに表示することができます。また、svv_external_schemas システムテーブルをクエリし、外部スキーマが正常に作成されたことを検証することもできます。次のスクリーンショットを参照してください。

S3 インベントリレポートを、最初にデータを Amazon Redshift に移動する必要なく、Amazon Redshift から直接クエリすることができるようになりました。次のスクリーンショットは、Amazon Redshift コンソールでクエリエディタを使ってこれを行う方法を示しています。

分析用に S3 サーバーアクセスログを設定する

次の図は、このソリューションのデータフローを示しています。

次の手順は、上で説明されたデータフロー図を要約したものです。

  • S3 サーバーアクセスログは、設定した S3 バケットに配信されます。
  • これらのサーバーアクセスログは次に、Amazon Redshift からクエリできるよう直接アクセス可能になります (以下で説明する通り、この目的では Redshift Spectrum で CREATE EXTERNAL TABLE を使用するものとしていることに注意)。
  • S3 サーバーアクセスログおよびコストと使用状況レポート (別の S3 バケットで利用可能) で、分析への参加およびクエリの準備ができています。

S3 サーバーアクセスログは S3 バケットに配信されます。サーバーアクセスログの設定について詳細は、「Amazon S3 サーバーアクセスのログ記録」を参照してください。

次のスクリーンショットは、サーバーアクセスログの S3 バケット構造を示しています。

サーバーアクセスログファイルは、連続した改行区切りログ記録として構成されています。各ログ記録は 1 つのリクエストを示し、スペース区切りのフィールドで構成されています。次のコードは、ログ記録の例です。

b8ad5f5cfd3c09418536b47b157851fb7bea4a00486471093a7d765e35a4f8ef s3spendanalysisblog [23/Sep/2018:22:10:52 +0000] 72.21.196.65 arn:aws:iam::<AWS Account #>:user/shayons D5633DAD1063C5CA REST.GET.LIFECYCLE - "GET /s3spendanalysisblog?lifecycle= HTTP/1.1" 404 NoSuchLifecycleConfiguration 332 - 105 - "-" "S3Console/0.4, aws-internal/3 aws-sdk-java/1.11.408 Linux/4.9.119-0.1.ac.277.71.329.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.181-b13 java/1.8.0_181" -

外部テーブルを作成する

S3 サーバーアクセスログを外部テーブルとして定義することができます。外部スキーマはすでにあるため、次のコードを使用して外部テーブルを作成します。この投稿では RegEx SerDe を使用して、S3 サーバーアクセスログに表示される全てのフィールドで正確な解析を可能にするテーブルを作成します。次のコードを参照してください。

CREATE EXTERNAL TABLE spectrum_schema.s3accesslogs(
BucketOwner                   varchar(256),
Bucket                        varchar(256),
RequestDateTime               varchar(256),
RemoteIP                      varchar(256),
Requester                     varchar(256),
RequestID                     varchar(256),
Operation                     varchar(256),
Key                           varchar(256),
RequestURI_operation          varchar(256),
RequestURI_key                varchar(256),
RequestURI_httpProtoversion   varchar(256),
HTTPstatus                    varchar(256),
ErrorCode                     varchar(256),
BytesSent                     varchar(256),
ObjectSize                    varchar(256),
TotalTime                     varchar(256),
TurnAroundTime                varchar(256),
Referrer                      varchar(256),
UserAgent                     varchar(256),
VersionId                     varchar(256))
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  'input.regex' = '([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) \"([^ ]*) ([^ ]*) ([^ ]*)\" (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\") ([^ ]*)'
  )
STORED AS TEXTFILE
LOCATION
  's3://s3spendanalysisblog/accesslogs/';

データを検証する

Amazon Redshift の外部テーブルデータを検証できます。次のスクリーンショットは、Amazon Redshift コンソールでクエリエディタを使ってこれを行う方法を示しています。

これで、データを分析する準備ができました。

Amazon Redshift を使用してデータを分析する

この記事では、S3 バケット内で 1 日に 1 つの CUR ファイルを所有します。ファイル自体は月単位の階層で編成されています。次のスクリーンショットを参照してください。

各日次ファイルは、以下の CUR データのファイルで構成されます。

  • myCURReport-1.csv.gz – データ自体の圧縮ファイル
  • myCURReport-Manifest.json – ファイルのメタデータを含む JSON ファイル
  • myCURReport-RedshiftCommands.sql – Redshift マニフェストファイルから CUR テーブルを作成する Amazon Redshift テーブル作成スクリプトおよび COPY コマンド
  • myCURReport-RedshiftManifest.json – CUR テーブルを作成する Amazon Redshift マニフェストファイル

Amazon Redshift の使用は、この分析を実施するための多数ある方法の 1 つです。Amazon Redshift は高速なフルマネージド型クラウドデータウェアハウスであり、標準 SQL や既存のビジネスインテリジェンス (BI) ツールを使用して、すべてのデータをシンプルかつコスト効率よく分析できます。Amazon Redshift では、使い慣れた SQL ベースのクライアントと、標準の ODBC および JDBC 接続を使用する BI ツールによる、構造化データに対する高速クエリが可能です。クエリは複数の物理ソースに分散され、並列化されます。

これで、Amazon Redshift SQL クエリエディタで SQL クエリを実行する準備ができました。この記事では、PostgreSQL のターミナルベースのフロントエンドである psql クライアントツールも使用して、クラスター内のデータをクエリします。

このデータをクエリするには、次の手順を実行します。

  1. 分析用のテーブルを含むカスタムスキーマを作成します。次のコードを参照してください。
    create schema if not exists redshift_schema;

    データベースオブジェクトへのユーザーアクセスを制御するには、パブリック以外のスキーマでテーブルを作成する必要があります。

  2. S3 の CUR SQL ファイルを使用して、Amazon Redshift で最新月の CUR テーブルを作成します。次のコードを参照してください。
    create table redshift_schema.AWSBilling201910 (
    identity_LineItemId VARCHAR(256),
    identity_TimeInterval VARCHAR(100),
    bill_InvoiceId VARCHAR(100),
    bill_BillingEntity VARCHAR(10),
    bill_BillType VARCHAR(100),
    bill_PayerAccountId VARCHAR(100),
    bill_BillingPeriodStartDate TIMESTAMPTZ,
    bill_BillingPeriodEndDate TIMESTAMPTZ,
    lineItem_UsageAccountId VARCHAR(100),
    lineItem_LineItemType VARCHAR(100),
    lineItem_UsageStartDate TIMESTAMPTZ,
    lineItem_UsageEndDate TIMESTAMPTZ,
    lineItem_ProductCode VARCHAR(100),
    lineItem_UsageType VARCHAR(100),
    lineItem_Operation VARCHAR(100),
    lineItem_AvailabilityZone VARCHAR(100),
    lineItem_ResourceId VARCHAR(256),
    lineItem_UsageAmount DECIMAL(11,2),
    lineItem_NormalizationFactor VARCHAR(10),
    lineItem_NormalizedUsageAmount DECIMAL(11,2),
    lineItem_CurrencyCode VARCHAR(10),
    lineItem_UnblendedRate DECIMAL(11,2),
    lineItem_UnblendedCost DECIMAL(11,2),
    lineItem_BlendedRate DECIMAL(11,2),
    lineItem_BlendedCost DECIMAL(11,2),
    lineItem_LineItemDescription VARCHAR(100),
    lineItem_TaxType VARCHAR(100),
    lineItem_LegalEntity VARCHAR(100),
    product_ProductName VARCHAR(100),
    product_alarmType VARCHAR(100),
    product_automaticLabel VARCHAR(100),
    product_availability VARCHAR(100),
    product_availabilityZone VARCHAR(100),
    product_clockSpeed VARCHAR(100),
    product_currentGeneration VARCHAR(100),
    product_databaseEngine VARCHAR(100),
    product_dedicatedEbsThroughput VARCHAR(100),
    product_deploymentOption VARCHAR(100),
    product_durability VARCHAR(100),
    product_ecu VARCHAR(100),
    product_edition VARCHAR(100),
    product_engineCode VARCHAR(100),
    product_enhancedNetworkingSupported VARCHAR(100),
    product_eventType VARCHAR(100),
    product_feeCode VARCHAR(100),
    product_feeDescription VARCHAR(100),
    product_fromLocation VARCHAR(100),
    product_fromLocationType VARCHAR(100),
    product_gpu VARCHAR(100),
    product_gpuMemory VARCHAR(100),
    product_group VARCHAR(100),
    product_groupDescription VARCHAR(100),
    product_instanceFamily VARCHAR(100),
    product_instanceType VARCHAR(100),
    product_instanceTypeFamily VARCHAR(100),
    product_io VARCHAR(100),
    product_labelingTaskType VARCHAR(100),
    product_licenseModel VARCHAR(100),
    product_location VARCHAR(100),
    product_locationType VARCHAR(100),
    product_maxThroughputvolume VARCHAR(100),
    product_maxVolumeSize VARCHAR(100),
    product_memory VARCHAR(100),
    product_messageDeliveryFrequency VARCHAR(100),
    product_messageDeliveryOrder VARCHAR(100),
    product_minVolumeSize VARCHAR(100),
    product_networkPerformance VARCHAR(100),
    product_normalizationSizeFactor VARCHAR(100),
    product_operation VARCHAR(100),
    product_physicalCpu VARCHAR(100),
    product_physicalGpu VARCHAR(100),
    product_physicalProcessor VARCHAR(100),
    product_processorArchitecture VARCHAR(100),
    product_processorFeatures VARCHAR(100),
    product_productFamily VARCHAR(100),
    product_protocol VARCHAR(100),
    product_queueType VARCHAR(100),
    product_region VARCHAR(100),
    product_servicecode VARCHAR(100),
    product_servicename VARCHAR(100),
    product_sku VARCHAR(100),
    product_storage VARCHAR(100),
    product_storageClass VARCHAR(100),
    product_storageMedia VARCHAR(100),
    product_subscriptionType VARCHAR(100),
    product_toLocation VARCHAR(100),
    product_toLocationType VARCHAR(100),
    product_transferType VARCHAR(100),
    product_usageFamily VARCHAR(100),
    product_usagetype VARCHAR(100),
    product_vcpu VARCHAR(100),
    product_version VARCHAR(100),
    product_volumeType VARCHAR(100),
    product_workforceType VARCHAR(100),
    pricing_RateId VARCHAR(100),
    pricing_publicOnDemandCost DECIMAL(11,2),
    pricing_publicOnDemandRate DECIMAL(11,2),
    pricing_term VARCHAR(100),
    pricing_unit VARCHAR(100),
    reservation_AmortizedUpfrontCostForUsage DECIMAL(11,2),
    reservation_AmortizedUpfrontFeeForBillingPeriod DECIMAL(11,2),
    reservation_EffectiveCost DECIMAL(11,2),
    reservation_EndTime TIMESTAMPTZ,
    reservation_ModificationStatus VARCHAR(100),
    reservation_NormalizedUnitsPerReservation BIGINT,
    reservation_RecurringFeeForUsage DECIMAL(11,2),
    reservation_StartTime TIMESTAMPTZ,
    reservation_SubscriptionId VARCHAR(100),
    reservation_TotalReservedNormalizedUnits BIGINT,
    reservation_TotalReservedUnits BIGINT,
    reservation_UnitsPerReservation BIGINT,
    reservation_UnusedAmortizedUpfrontFeeForBillingPeriod DECIMAL(11,2),
    reservation_UnusedNormalizedUnitQuantity BIGINT,
    reservation_UnusedQuantity BIGINT,
    reservation_UnusedRecurringFee DECIMAL(11,2),
    reservation_UpfrontValue BIGINT
    );
  3. 作成された CUR マニフェストファイルを使用して、最新月のデータを Amazon Redshift にロードします。次のコードを参照してください。
    copy AWSBilling201910 from 's3://ss-cur//myCURReport/20191001-20191101/fd76beee-0709-42d5-bcb2-bb45f8ba1aae/myCURReport-RedshiftManifest.json'
    credentials 'arn:aws:iam::<AWS_IAM_ROLE>'
    GZIP CSV IGNOREHEADER 1 TIMEFORMAT 'auto' manifest;
  4. Amazon Redshift テーブルにロードされたデータを検証します。次のコードを参照してください。
    select * from AWSBilling201910
    where lineItem_ProductCode = 'AmazonS3'
    and lineItem_ResourceId = 's3spendanalysisblog' limit 10;

    次のスクリーンショットは、データが Amazon Redshift テーブルに正常にロードされたことを示しています。

データベースセキュリティを管理する

どのユーザーがどのデータベースオブジェクトにアクセスできるかを制御することにより、Amazon Redshift でデータベースセキュリティを管理できます。オブジェクトが安全であることを確認するには、FINANCEADMIN の 2 つのグループを作成します。FINANCE には 2 人のユーザーが、ADMIN には 1 人のユーザーがいます。次の手順を実行します。

  1. ユーザーアカウントが割り当てられているグループを作成します。次のコードで 2 つの異なるユーザーグループを作成します。
    create group finance;
    create group admin;

    すべてのユーザーグループを表示するには、PG_GROUP システムカタログテーブルをクエリします (financeadmin がここに表示されます)。

    select * from pg_group:

  2. 異なる権限を持つ 3 つのデータベースユーザーを作成し、グループに追加します。次のコードを参照してください。
    create user finance1 password 'finance1Pass'
    in group finance;
    
    create user finance2 password 'finance2Pass'
    in group finance;
    
    create user admin1 password 'admin1Pass'
    in group admin;

    ユーザーが正常に作成されたことを検証します。ユーザーのリストを表示するには、PG_USER カタログテーブルをクエリします。

  3. redshift_schema 内のテーブル AWSBilling201910FINANCEグループには SELECT 権限を付与し、ADMIN グループにはすべての権限を付与します。次のコードを参照してください。
    grant select on table redshift_schema.AWSBilling201910 to group finance; 
    grant all on table redshift_schema.AWSBilling201910 to group admin;

    データベースセキュリティが正常に適用されているかどうかを確認できます。ユーザーfinance1 は、redshift_schema 内のテーブル AWSBilling201910 の名前を変更しようとしましたが、permission denied というエラーメッセージが表示されました (アクセスが制限されているため)。次のスクリーンショットは、このシナリオとそれに続くエラーメッセージを示しています。

例 S3 インベントリ分析

S3 料金はバケットごとに分割されます。次のクエリでは、個別の S3 バケットごとにデータストレージと転送コストを識別します。

SELECT
  "lineitem_productcode",
  "lineitem_usagetype",
  "lineitem_resourceid",
  b."storage_class",
  SUM(CASE
    WHEN "lineitem_usagetype" like '%Byte%' THEN "lineitem_usageamount"/1024
    ELSE "lineitem_usageamount"
  END) as "Usage",
  CASE
    WHEN "lineitem_usagetype" like '%Byte%' THEN 'TBs'
    ELSE 'Requests'
  END as "Usage Units",
  sum("lineitem_blendedcost") as cost
from awsbilling201902 a
  join spectrum_schema.data b
    on a.lineItem_ResourceId = b.bucket
where "product_productname" = 'Amazon Simple Storage Service'
group by
  "lineitem_productcode",
  "lineitem_usagetype",
  "lineitem_resourceid",
  b."storage_class"
order by
  sum("lineitem_blendedcost") desc;

次のスクリーンショットは、上記のクエリを実行した結果を示しています。

コストはストレージのタイプ (例、Glacier と標準ストレージ) により分割されます。

次のクエリでは、S3 ストレージクラス (使用量、非ブレンドコスト、ブレンドコスト) ごとに S3 データ転送コスト (リージョン内およびリージョン間) を識別します。

SELECT
 lineitem_productcode
 ,product_fromlocation
 ,product_tolocation,
  b.storage_class
 ,sum(lineitem_usageamount) usageamount
 ,sum(lineitem_unblendedcost) unblendedcost
 ,sum(lineitem_blendedcost) blendedcost
FROM
awsbilling201902 a
  join spectrum_schema.data b
ON
    a.lineItem_ResourceId = b.bucket
WHERE
 a.lineitem_productcode = 'AmazonS3'
 AND a.product_productfamily = 'Data Transfer'
GROUP BY
 1,2,3,4
ORDER BY
 usageamount desc;

次のスクリーンショットは、上記のクエリを実行した結果を示しています。

次のクエリでは、S3 料金、API リクエスト、ストレージ料金を識別します。

SELECT
 lineitem_productcode
 ,product_productfamily
 ,b.storage_class
 ,sum(lineitem_usageamount) usageamount
 ,sum(lineitem_unblendedcost) unblendedcost
 ,sum(lineitem_blendedcost) blendedcost
FROM
awsbilling201902 a
  join spectrum_schema.data b
ON
   a.lineItem_ResourceId = b.bucket
WHERE
 a.lineitem_productcode = 'AmazonS3'
  and a.product_productfamily <> 'Data Transfer'
GROUP BY
 1,2,3
ORDER BY
 usageamount desc;

次のスクリーンショットは、上記のクエリを実行した結果を示しています。

サーバーアクセスログのサンプルの分析クエリ

オペレーションタイプごとの S3 アクセスログ料金。次のクエリでは、個別の HTTP オペレーションのデータストレージと転送コストを識別します。

SELECT
  "lineitem_productcode",
  "lineitem_usagetype",
  "lineitem_resourceid",
  b."operation",
  b."httpstatus",
  b."bytessent",
  SUM(CASE
      WHEN "lineitem_usagetype" like '%Byte%'
        THEN "lineitem_usageamount" / 1024
      ELSE "lineitem_usageamount"
      END) as "Usage",
  CASE
  WHEN "lineitem_usagetype" like '%Byte%'
    THEN 'TBs'
  ELSE 'Requests'
  END  as "Usage Units",
  sum("lineitem_blendedcost") as cost
from awsbilling201902 a
  join spectrum_schema.s3accesslogs b
    on a.lineItem_ResourceId = b.bucket
where "product_productname" = 'Amazon Simple Storage Service'
group by
  1, 2, 3, 4, 5, 6
order by
  sum("lineitem_blendedcost") desc;

次のスクリーンショットは、上記のクエリを実行した結果を示しています。

次のクエリでは、S3 オペレーションと HTTP ステータス (使用量、非ブレンドコスト、ブレンドコスト) によって S3 データ転送コスト (リージョン内およびリージョン間) を識別します。

SELECT
 lineitem_productcode
 ,product_fromlocation
 ,product_tolocation
 ,b.operation
 ,b.httpstatus
 ,sum(lineitem_usageamount) usageamount
 ,sum(lineitem_unblendedcost) unblendedcost
 ,sum(lineitem_blendedcost) blendedcost
FROM
awsbilling201902 a
  JOIN spectrum_schema.s3accesslogs b
ON
   a.lineItem_ResourceId = b.bucket
WHERE
 a.lineitem_productcode = 'AmazonS3'
 AND a.product_productfamily = 'Data Transfer'
GROUP BY
 1,2,3,4,5
ORDER BY
 usageamount desc;

次のスクリーンショットは、上記のクエリを実行した結果を示しています。

次のクエリでは、S3 料金、API リクエスト、ストレージ料金を識別します。

SELECT
 lineitem_productcode
 ,product_productfamily
 ,b.operation
 ,b.httpstatus
 ,sum(lineitem_usageamount) usageamount
 ,sum(lineitem_unblendedcost) unblendedcost
 ,sum(lineitem_blendedcost) blendedcost
FROM
awsbilling201902 a
  JOIN spectrum_schema.s3accesslogs b
ON
   a.lineItem_ResourceId = b.bucket
WHERE
 a.lineitem_productcode = 'AmazonS3'
  and a.product_productfamily <> 'Data Transfer'
GROUP BY
 1,2,3,4
ORDER BY
 usageamount desc;

次のスクリーンショットは、上記のクエリを実行した結果を示しています。

全体的なデータフロー図

次の図は、このソリューションの完全なデータフローを示しています。

まとめ

AWS Glue は、クラウドネイティブでセキュア、そして効率的な方法で S3 バケットに保存されたデータを自動的に探索するための、容易で便利な方法を提供します。この記事では、AWS Glue と Amazon Redshift を使用して、コストおよび使用状況レポートを利用して S3 支出を分析する方法をご紹介しました。また、ユーザーとグループを介して Amazon Redshift のデータベースセキュリティを管理するためのベストプラクティスも学びました。このフレームワークを使用すれば、AWS マネジメントコンソールを数回クリックするだけで、S3 バケットの支出の分析を開始できます!

ご質問またはご提案は、下のコメント欄にお寄せください。

 


著者について

Shayon Sanyal は、AWSのグローバル金融サービスのデータレイクのデータアーキテクトです。