Zenn
📖

AWSコストをSlack通知&可視化!BigQuery × Looker Studio構成メモ

2025/03/31に公開

AWSコストをSlack通知&可視化!BigQuery × Looker Studio構成メモ

AWSコストの見える化を目的に、BigQuery と Looker Studio を使ってダッシュボードを構築しました。
今回は CSVファイルからのデータ取り込みを前提とした構成で、集計・可視化・通知までを一通り自動化しています。
実装していく中でハマりどころや工夫したポイントもあったので、備忘録としてまとめておきます。


構成概要

  • データソース:コストのcsvファイル(リセラー契約のためCost Explorerが使えない前提)
  • 集計・加工:BigQuery
  • 可視化:Looker Studio
  • アラート通知:GAS + Slack API

1. データの加工は基本BigQueryでやる

Looker Studioでもデータのフィルタや計算はできますが、柔軟性や再利用性に欠ける部分が多く、以下の理由から BigQuery側でViewを作成して集計ロジックを完結させる 方が効率的でした。

  • Looker Studioでは項目の追加や変換がちょっと煩雑
  • Viewを作っておけば、複数のダッシュボードで再利用可能
  • 加工・フィルタ・計算はBigQueryで完結させた方が圧倒的に管理しやすい

例:BigQueryのView

以下は、前月との差分(増減額)と増減率(%)を計算するBigQueryのクエリ例です。
ウィンドウ関数 LAG() を使って、同一 billing_account_id × service ごとに前月の値を取得しています。

CREATE OR REPLACE VIEW `myproject.dataset.monthly_cost_diff` AS
WITH monthly_base AS (
  SELECT
    billing_account_id,
    service,
    EXTRACT(YEAR FROM usage_start_time) AS year,
    EXTRACT(MONTH FROM usage_start_time) AS month,
    DATE_TRUNC(usage_start_time, MONTH) AS month_date,
    SUM(cost) AS total_cost
  FROM
    `myproject.dataset.raw_cost_data`
  GROUP BY
    billing_account_id, service, year, month_date
),
with_diff AS (
  SELECT
    billing_account_id,
    service,
    FORMAT_DATE('%Y-%m', month_date) AS month,
    total_cost,
    LAG(total_cost) OVER (
      PARTITION BY billing_account_id, service
      ORDER BY month_date
    ) AS prev_month_cost
  FROM
    monthly_base
)
SELECT
  billing_account_id,
  service,
  month,
  total_cost,
  prev_month_cost,
  SAFE_DIVIDE(total_cost - prev_month_cost, prev_month_cost) * 100 AS diff_percent,
  total_cost - prev_month_cost AS diff_amount
FROM
  with_diff;

出力カラム

カラム名 説明
billing_account_id STRING 課金アカウントID
service STRING サービス名(例: EC2, S3など)
month STRING 対象月(例: 2025-03)
total_cost FLOAT64 今月の合計コスト(円)
prev_month_cost FLOAT64 前月の合計コスト(円)
diff_percent FLOAT64 コストの増減率(%)
diff_amount FLOAT64 差分金額(今月 - 前月)(円)

2. コスト上昇をSlack通知するためにGAS + スプレッドシートを使う

ダッシュボードで確認するだけでなく、「コストが上がったときに通知がほしい」という要望もあったため、Slack通知の仕組みもあわせて作成しました。
構築の中でスプレッドシートとGASの連携まわりで少し詰まった部分があったので、そのあたりもまとめておきます。

構成:

  1. BigQueryのViewで差分を計算する
  2. そのViewのデータをスプレッドシートに連携
  3. GASでそのデータを処理し、Slack API経由で通知を送信

詰まったポイント:

  • スプレッドシートに連携されたデータは、GASから直接アクセスできない。Slackと直接連携もできない。
    • → 解決策:抽出機能を使い別シートに書き出し、それをGASで読み取るようにする 。この場合でも定期的な更新の設定はできた。

例:GASでSlack通知するコード

function notifyCostAlert() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("alert_data");
  const data = sheet.getRange(2, 1, sheet.getLastRow() - 1, 7).getValues(); 
  data.forEach(row => {
    const [
      billingAccountId,
      service,
      month,
      totalCost,
      prevMonthCost,
      diffPercent,
      diffAmount
    ] = row;

    // 閾値:1,000円以上増えていたら通知
    if (diffAmount > 1000) {
      const payload = {
        text: `⚠️ AWSコストが増加しています
` +
              `• アカウント: ${billingAccountId}
` +
              `• サービス: ${service}
` +
              `• 対象月: ${month}
` +
              `• 前月: ¥${prevMonthCost}
` +
              `• 今月: ¥${totalCost}
` +
              `• 差分: ¥${diffAmount.toFixed(0)}${diffPercent.toFixed(1)}% 増)`
      };

      const options = {
        method: "post",
        contentType: "application/json",
        payload: JSON.stringify(payload)
      };

      UrlFetchApp.fetch("https://hooks.slack.com/services/XXX/YYY/ZZZ", options);
    }
  });
}

3. Looker Studioのバグに注意

Looker Studioは便利なんですが、表示が不安定になることが結構あります

よくある症状:

  • 項目を変更しても反映されない
  • 「エラー」と表示されるが、実際は問題なし

対策:

  • シンプルにブラウザをリロードすると大体直ります

まとめ

今回紹介した構成では、コストデータの取得はCSVファイル、集計・加工はBigQuery、可視化はLooker Studio、アラート通知はGASとSlackの連携という役割分担にしました。

データの整形はBigQueryのViewで行うことで、再利用性が高く、管理しやすい形にできました。また、Looker Studioはあくまで見た目に徹し、複雑な計算や前月との比較などはBigQueryに任せた方がスムーズです。

Cost Explorerが使えない環境でも、CSVファイルからダッシュボードを作ることができました。

株式会社ソニックムーブ

Discussion

ログインするとコメントできます