MoTLab -GO Inc. Engineering Blog-MoTLab -GO Inc. Engineering Blog-

インフラコストをBigQueryで集約管理

SREBigQuery
December 05, 2022

 MoTでは、クラウドインフラサービスとして主にAWSとGCPを利用しており、コストの管理・確認についてもそれぞれのクラウドインフラサービスが提供しているコストレポートやダッシュボードを利用して確認しています。

 今回、AWSとGCPにまたがっているサービスや、両方のコストレポートを行き来せずに確認できる環境が欲しいという要望から、AWSとGCPのコストをGCPのBigQueryに集約させる仕組みを検討し準備しました。そちらの構成内容を紹介します。


はじめに

 SREグループ・ヒロチカです。MoTでは、サービスのクラウドインフラの設計から構築・運用までを担当しています。

 MoTでは、クラウドインフラサービスとして主にAWS・GCPを利用していますが、コスト管理においては、それぞれのクラウドインフラサービスの課金系ダッシュボードを参照しているため、全体のインフラコスト感を一度に把握するのが難しいという課題があげられていました。

 そこで、GCPのコストはコストレポートからそのままBigQueryに、AWSのコストはBigQuery Data Transfer Serviceを利用してS3からBigQueryにデータをコピーし、コストデータの全てをBigQuery に集約してみました。

構成

構成図

An image from Notion

 GCPのbilling情報は、組織内で紐づけている課金アカウント単位ごとそれぞれで、日次でデータをBigQueryに直接出力するように設定します。

 AWSのコストレポートは、同一アカウントにのみ出力可能なので、請求アカウントから日次で同じ請求アカウントにあるS3に出力するよう設定した後、S3のクロスアカウント レプリケーションを使い、サブアカウントのS3へと課金データのレプリケーションをしています。これは、請求アカウントに対して、直接BigQuery Data Transferが参照するルートを作りたくないという弊社内のセキュリティーポリシーによるものになります。

 BigQuery Data Transferは、レプリケーション先のS3バケットのデータを日次で参照し、データを取得してBigQueryにデータを流します。この際、AWSのコストレポートが、月初からレポートが出力された日でのデータが全て入ってくるため、取り込み時間等でパーティションを分けておくとBigQueryの参照時のコスト削減につながりデータも扱いやすくなります。

 また、AWSとGCPの課金データを集めるデータセットはデータ出力設定の都合上、分けています。

 コストデータが集まっているBigQueryに対して、ユーザが直接参照したりRedash経由でアクセスをし、コストデータにアクセスする構成です。

構築内容

GCP

 課金データを集めたい請求先アカウントの設定が可能なユーザで設定します。設定手順は、基本、公式サイトに則っています。

 参照: Cloud Billing データを BigQuery にエクスポートする

 MoTでは、課金データを集めるためのGCPプロジェクトを作成しており、そこに課金データを集めるためのBigQueryのデータセットとテーブルを準備し出力しています。これらは、エクスポート設定する前に作成しておきます。

  • [お支払い] > [課金データエクスポート] > [BIGQUERY EXPORT]
An image from Notion

AWS

 構成図通りに設定します。主な設定内容としては下記になります。

  • AWSの請求アカウント上にて、コストレポートをS3に出力
  • 請求アカウントで出力したS3のレポートを、連携するためのサブアカウントのS3にクロスアカウントでレプリケーションを行う設定
  • BigQuery Data Transfer Serviceの設定

コストレポート

  • 請求アカウントにて
    • billing > [Cost & Usage reports] > [レポートの作成]

 S3バケットや、レポート名/パスなどは、それぞれの環境に合わせて設定します。今回は、社内での要件に合わせ、日別で新しくレポートを出力する形としました。

 レポートの明細項目も適宜、要件に合わせて設定してください。

S3クロスアカウントレプリケーション

  • サブアカウント上にレプリケーション先のS3バケットを作成後、請求アカウントにて設定
    • S3 > [対象バケット] > [管理] > [レプリケーションルールを作成]

An image from Notion

()

 基本的には、一般的なレプリケーションルールの設定で問題ありません。レプリケーションオプションについては請求アカウント側を正とするため、ファイルの削除について有効としています。

 また、BigQuery Data Transferからアクセスを可能にするために、レプリケーションルールの設定時、[オブジェクト所有者を送信先バケット所有者に変更]にチェックを入れておきます。

 その他、適宜、移行先のストレージクラスやAWS KMSキー等も環境に合わせて設定してください。

An image from Notion

()

BigQuery Data Transfer Service

 こちらも、基本的な設定は、公式サイトに則って行います。

 S3からデータを転送するにあたり、対象S3に対するRead権限を持ったIAMユーザをAWS側で作成し、Access Key 等を作成しておきます。

 また、GCPの課金データ設定時と同様に、事前にAWSの課金データ用のBigQueryデータセットとテーブルを作成しておきます。

An image from Notion

()BigQuery

  • 課金データを取り込みたいGCPプロジェクト
    • BigQuery > [データ転送] > [+ 転送を作成]

An image from NotionAn image from Notion

()

 S3 URIについては、ランタイムパラメータを利用し実行時のタイムスタンプや時間オフセットの設定も可能なため、日付で整理されているバケットを日別で取得可能になっています。利用できるパラメータはドキュメント(転送でのランタイムパラメータ)を参照ください。

 スケジュールのオプションも適宜、要件に合わせて設定してください。

課金データ

 ここまで正しく設定されていれば、下記のようにAWSの課金データがテーブルに挿入されます。

An image from Notion

 

Terraformによる設定

 MoTでは、インフラの構成管理はterraformで行っており、今回の構築もterraformにて行っています。下記、一部抜粋します。

# 送信元 s3
resource "aws_s3_bucket" "report" {
  bucket = "任意のバケット名"
}

# 送信元 s3バケットポリシー(s3レプリケーション設定のため)
resource "aws_s3_bucket_policy" "report-bucket-policy" {
  bucket = aws_s3_bucket.report.id
  policy = <<POLICY
{
    "Version": "2008-10-17",
    "Id": "policy-id",
    "Statement": [
        {
            "Sid": "001",
            "Effect": "Allow",
            "Principal": {
                "Service": "billingreports.amazonaws.com"
            },
            "Action": [
                "s3:GetBucketAcl",
                "s3:GetBucketPolicy"
            ],
            "Resource": "課金データ送信元s3のarn",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "課金データ送信元のs3のあるAWSアカウントID",
                    "aws:SourceArn": "arn:aws:cur:us-east-1:課金データ送信元のs3のあるAWSアカウントID:definition/*"
                }
            }
        },
        {
            "Sid": "002",
            "Effect": "Allow",
            "Principal": {
                "Service": "billingreports.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "課金データ送信元のs3のarn/*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "課金データ送信元のs3のあるAWSアカウントID",
                    "aws:SourceArn": "arn:aws:cur:us-east-1:課金データ送信元のs3のあるAWSアカウントID:definition/*"
                }
            }
        }
    ]
}
POLICY
}

# コストレポート
resource "aws_cur_report_definition" "cur_report" {
  report_name                = "任意のコストレポート名"
  time_unit                  = "DAILY"
  format                     = "textORcsv"
  compression                = ""
  additional_schema_elements = ["RESOURCES"]
  s3_bucket                  = aws_s3_bucket.report.bucket
  s3_prefix                  = "path/to/cost_and_usage_report"
  s3_region                  = "us-east-1"
  additional_artifacts       = []
  report_versioning          = "CREATE_NEW_REPORT"
}

・・・

設定のポイント

  • AWSのコストレポートは、現状us-east-1のみ対応しているためterraformで管理する際注意が必要です。
  • BigQuery側のテーブルについては、AWSのコストレポートのデータ内容に合わせ、日別の取り込み時間での分割基準にしています。
  • S3レプリケーションの設定では、バケットの所有者をレプリケーション先にしておかなければBigQuery Data Transfer側から参照できずAccess Deniedのエラーが出てしまいます。
  • BigQuery Data Transfer Serviceが取り込めるデータと、AWSのコストレポートの出力データの互換性があるファイル形式がparquetしかなかったため、今回はparquet形式でデータの取り込みをしています。また、ファイルが複数に分かれる場合のためにS3 URIの連番がふられる部分を*で指定し対応しています。
  • BigQuery Data Transfer Serviceの設定内、S3 URIについては設定後の編集ができないため、バケットの指定などを間違えた場合にはデータ転送設定の再作成が必要となってしまいます。

課題・今後の展開

 AWSのコストレポートは、月初からその当日までの詳細なコスト履歴が細かく記載されたデータとなっているため、カラム数やレコード数が非常に多く、細かく分析するには必要な内容ですが、ざっくりとしたコストの全体感を知りたい場合には、情報過多な部分もあり、今後、参照するユーザの要件に合わせて、例えば、AWS Cost Explorerなどでデータをある程度集計したものを日々出力し、それを取り込む構成なども検討できればと思っています。

 AWSの課金データを取り込む際のGCPの構成部分については、コンソール画面上での検証・調整を必要とする箇所があったため、まだterraform化しておらず、運用が安定したタイミングでterraformでの構成管理化を行う予定です。

 今後の展開として、全社的に気軽にコストを確認できるレポートを発行したり、集約したデータを用いて事前に設定した想定コストを超えた場合にアラートする仕組みを構築したり、不要なまま起動してしまっているリソースの削除漏れをコスト面から検知する仕組み等も考えていければと思っています。

おわりに

 今回は、AWSとGCPの課金データをBigQueryに集約する構成を紹介いたしました。GCPはそのまま、BigQueryへとエクスポートすることが可能でしたが、BigQuery Data Transfer Serviceが、S3からのデータ転送に対応したことで、今回のような構成が実現可能となりました。弊社の場合は、一度S3のクロスアカウントレプリケーションを挟んだことにより、少し設定が複雑になっていますが、BigQuery Data Transfer Serviceの設定自体は非常にシンプルなため、課金データに限らずいろんな場面で利用可能なサービスだと思います。

 この記事が、課金データをBigQueryで管理したいと思っている方の参考になれば幸いです。


We're Hiring!

📢
Mobility Technologies ではともに働くエンジニアを募集しています。

興味のある方は 採用ページ も見ていただけると嬉しいです。

Twitter @mot_techtalk のフォローもよろしくお願いします!