はじめに
Google Cloudの課金データを日次でSlackに通知する仕組みを作成してみたため、まとめてみました。
下記のサイトを参考にしています。
BigQuery 破産で泣かないために。。GCP 利用料金を bot で Slack に通知してみた
GASで手軽に SlackへのKPI通知Botを作る
BigQuery課金情報をslackへの通知機能を作る
1. 使用したもの
- Cloud Billing
- BigQuery
- Google Apps Script
- Slack
2. 仕組み
2-1. 構成図
2-2. 処理の流れ
① Google Cloudの課金データをBigQueryのデータセットにエクスポートする
② BigQueryに対しGoogle Apps Scriptを使用してクエリを実行する
③ クエリの結果をSlackに通知する
3. 設定内容
サービスごとの設定内容を説明します。
※Google CloudのCloud BillingやBigQueryのアクセス権限がある前提で説明します。
3-1. Cloud Billing、BigQuery
GCPコンソールのナビゲーションメニューの「お支払い」から「課金データのエクスポート」を選択します。
BigQueryにエクスポートする課金データは下記の3タイプがあります。
・標準の使用料金データ
・詳細な使用料金データ
・料金データ
それぞれの課金データの説明はCloud Billingのドキュメントを参照ください。
今回は標準の使用料金データをBigQueryのデータセットにエクスポートします。
「標準の使用料金」の「設定を編集」を選択します。
課金データをエクスポートするプロジェクトと、エクスポート先のBigQueryのデータセットを指定します。
既に課金データをエクスポートする際に使用するデータセットを作成済みの場合は、そちらを選択してください。
今回は課金データのエクスポート設定の中でデータセットを作成します。
「データセット」から「新しいデータセットの作成」を選択します。
「データセットID」と「データのロケーション」を選択します。
今回はテーブルの有効期限や詳細オプションの暗号化は設定しません。
データセットの作成後、作成したデータセットが課金データのエクスポートに設定されていることを確認し、保存します。
すると、課金データのエクスポート設定が有効になることを確認できます。
GCPコンソールのナビゲーションメニューの「BigQuery」から「SQLワークスペース」を選択し、前述した手順で作成したデータセットが存在することを確認できます。
課金データのエクスポートの設定後、しばらく放置してから確認すると、課金データがエクスポートされているはずです。
※今回は3時間ほどかかりました。
データセットに対しクエリを実行し、サービスごとの課金データを参照してみます。
▼クエリ
SELECT
DATE(TIMESTAMP_ADD(usage_start_time, INTERVAL 9 HOUR)) AS query_date,
service.description,
SUM(cost) AS cost,
currency
FROM
`プロジェクトID.データセット名.テーブル名`
GROUP BY
query_date,
service.description,
currency
HAVING
query_date = DATE_ADD(DATE(TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 9 HOUR)), INTERVAL -1 DAY)
ORDER BY
query_date;
3-2. Slack
先に、課金データを通知するためのSlackチャンネルを作成します。
今回は下記のように作成してみました。
チャンネルを作成したら、slack apiにてSlackに通知するためのアプリを作成します。
作成するアプリの名前を入力し、連携先のSlackワークスペースを選択した後、「Create App」を選択します。
作成したSlackチャンネルにアプリを連携していきます。
アプリとSlackチャンネルが連携されると、Slackチャンネルに下記のメッセージが表示されます。
3-3. Google Apps Script
前述した方法で、Google Cloudの課金データをBigQueryのデータセットにエクスポートできるようにしました。
Google Apps ScriptからBigQueryに対しクエリを実行して、Google Cloudの課金データを取得し、結果をSlackに通知します。
Google Apps Scriptのサイトで「Start Scripting」を選択します。
Google Apps Scriptのコンソール画面が開いたら、「新しいプロジェクト」を選択します。
下記の処理を実施するプログラムをJavaScriptで記載します。
・Google Cloudの課金データを取得する
・Slackメッセージを組み立て、ポストする
▼プログラム
// BigQueryに対しクエリ実行
function runQuery() {
var projectId = "プロジェクトID";
var request = {
"query" : "SELECT DATE(TIMESTAMP_ADD(usage_start_time, INTERVAL 9 HOUR)) AS query_date, service.description, SUM(cost) AS cost, currency FROM `プロジェクトID.データセット名.テーブル名` GROUP BY query_date, service.description, currency HAVING query_date = DATE_ADD(DATE(TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 9 HOUR)), INTERVAL -1 DAY) ORDER BY query_date;",
"useLegacySql": false,
};
var queryResults = BigQuery.Jobs.query(request, projectId);
var jobId = queryResults.jobReference.jobId;
var sleepTimeMs = 500;
while (!queryResults.jobComplete) {
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
}
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
pageToken: queryResults.pageToken
});
rows = rows.concat(queryResults.rows);
}
return rows
}
// Slackメッセージの組み立て、ポスト
function postSlack(date, description, cost, currency) {
// メッセージを組み立てる
var body = {
"attachments" : [
{
"color": "00FF00",
"fields": [
{
"title": "日付",
"value": date,
"short": true
},
{
"title": "サービス名",
"value": description,
"short": true
},
{
"title": "金額",
"value": cost + " [" + currency + "]",
"short": true
}
],
}
]
};
// ポスト
var webhookURL = 'Webhook URL';
var options = {
'method' : 'POST',
'contentType' : 'application/json',
'payload' : JSON.stringify(body),
};
UrlFetchApp.fetch(webhookURL, options);
}
// この関数を最初に実行する
function main(){
var rows = runQuery();
var date = "";
var description= "";
var cost= "";
var currency= "";
for (let i=0; i<rows.length; i++) {
date = rows[i].f[0].v;
description = rows[i].f[1].v;
cost = rows[i].f[2].v;
currency = rows[i].f[3].v;
postSlack(date, description, cost, currency);
}
}
注意点(つまづいた箇所)
1点目:プロジェクトを実行する際に、最初に実行する関数を選択してください。
ここで最初に実行する関数を指定し忘れていて、うまく動かなかったことがあります。
2点目:サービス「BigQuery API」を有効にしてください。
こちらを有効にしておかないと、BigQueryでクエリを実行する際に下記のようなエラーが発生します。
▼実行ログ
3-4. 動作確認
それでは、正常に動作するか確認してみます。
画面上部の「実行」ボタンをクリックして実行します。
ソースの気になる箇所にブレークポイントを貼り、デバッグ実行することもできます。
▼実行ログ
▼Slackの通知用チャンネル
動きました。
実行したのが2022-06-01で、前日(2022-05-31)の課金データがサービスごとに通知されました。
プログラムが動作することは確認できたため、これを定期的に実行するように設定します。
今回はGoogle Cloudの課金データを日次で通知したいので、下記のように設定します。
設定が完了したら、「保存」を選択します。
指定した日時でSlackに通知されるのを待ちます。
翌日、午前9時~10時の間に実行するように設定していましたが、無事Slackチャンネルに通知されていることを確認できました。
おわりに
今回はGoogle Cloudの課金データを通知するといったことをやってみました。
Google Cloudは最近触り始めて、今回使用したサービス以外の物はまだ使ったことがないので、
どんどん活用しながら学んでいきたいと思います。