これは何?
[GCP お支払い > レポート] から参照可能な料金体系を…
一日一回、slack に定期報告する bot を作成する
注意事項
docker, cloud sdk 環境が必要
メールで予算を管理するだけで十分な場合
[お支払い > 予算とアラート] から、予算とアラートを設定可能
機能としては、事前に設定した予算をオーバーした際にアラートメールを送信してくれる
どちらも設定しておくと安心
GCP の料金を slack で管理する
#01. slack の Messaging API を作成
slack の Incoming Webhook を設定し、詳細ページに遷移して以下を行う
Webhook URL をコピー
チャンネルへの投稿 から通知先を選択
名前・アイコンをカスタマイズ
Webhook URL を用いて以下のスクリプトを実行すると slack に Hello World! というメッセージが送信される
# python の場合
import json
import os
import requests
WEBHOOK_URL = os.environ["WEBHOOK_URL"]
data = json.dumps({"text": "Hello World!"})
requests.post(WEBHOOK_URL, data=data)
#02. BigQuery で課金データを保持するデータセットを作成
GCP の [BigQuery > エクスプローラ] の左のツリーから、プロジェクト名の右にある [: > データセットを作成] からデータセットを作成
ここでは add_billing_data という名前で作成
#03. GCP 課金データをエクスポートする
[GCP の お支払い > 課金データのエクスポート] から BIGQUERY EXPORT の設定を行う
#02. で設定したデータセット名 add_billing_data を指定して保存
#04. Cloud Functions で実行スクリプトを作成
GCP の Cloud Functions 関数の作成から、❶構成 を設定
❷コード にて以下のスクリプトをペーストしてデプロイ
ランタイム: Python 3.9
ソースコード: インラインエディタ
エントリポイント: notify_slack
# main.py
# -*- coding: utf-8 -*-
# 標準出力は Cloud Logging にて確認可能
import datetime as dt
import json
import base64
from pprint import pprint
import requests
from flask.wrappers import Request
from google.cloud import bigquery
QUERY = """
SELECT
service.description as Service,
(SUM(CAST(cost * 1000000 AS int64))
+ SUM(IFNULL((SELECT SUM(CAST(c.amount * 1000000 as int64))
FROM UNNEST(credits) c), 0))) / 1000000 as Cost
FROM `{sql_database}`
WHERE project.name = '<project/name>' AND invoice.month = '{month}'
GROUP BY Service
ORDER BY Cost DESC
;
"""
def notify_slack(request: Request, context=None):
WEBHOOK_URL = "<set/your/URL>"
SQL_DATABASE = "<sql/database>"
INVOICE_MONTH = dt.datetime.now(dt.timezone.utc).strftime("%Y%m")
year, month = INVOICE_MONTH[:4], INVOICE_MONTH[4:]
# GCP 利用料金取得
query = QUERY.format(sql_database=SQL_DATABASE, month=INVOICE_MONTH)
client = bigquery.Client()
query_job = client.query(query)
rows = query_job.result()
# slack にメッセージを送信
messages = []
total_cost = 0
for row in rows:
desc = row.Service + " "*50
total_cost += row.Cost
total = " "*10 + f"{row.Cost:.2f}"
text = f"・ {total[-10:]} 円 \\t {desc[:20]}\\t"
messages.append(text)
messages = [f"{year}年{month}月:\\t計 {total_cost:.2f} 円", "-"*40] + messages
message = "\\n".join(messages)
print(message)
try:
post_data = json.dumps({
"text": message,
})
r_post = requests.post(WEBHOOK_URL, data=post_data)
print(r_post.status_code) # 201
print(r_post)
return "success"
except Exception as e:
print(e)
return "error"
# requirements.txt
flask
requests
google-cloud-bigquery
(注意)上記 Python スクリプト内で実行している SQL クエリ実行時の処理サイズは事前に確認すること
#05. Cloud Run で実行スクリプトを実行
ローカルの適当な workspace に移動
script.sh を以下のように作成
# Cloud Function のページに指定してある URL に変更
URL="<https://(.*?).a.run.app>"
# 以下を実行
curl -m 70 -X POST $URL \\
-H "Authorization: bearer $(gcloud auth print-identity-token)" \\
-H "Content-Type: application/json" \\
-d '{
"data": {"message": "Hello World"}
}'
Dockerfile を以下のように作成
FROM google/cloud-sdk:latest
ENV APP_HOME /app
COPY script.sh $APP_HOME/
RUN chmod +x $APP_HOME/script.sh
CMD $APP_HOME/script.sh
docker イメージをビルド
PROJECT_ID="<your project>"
NAME="<your app name>"
TAG="gcr.io/${PROJECT_ID}/${NAME}"
docker build . -t $TAG --no-cache
以下を実行
# レジストリへプッシュ
gcloud builds submit --tag ${TAG}:latest
# ジョブを作成
gcloud alpha run jobs create ${NAME} \\
--image ${TAG} \\
--region asia-northeast1
# 作成したジョブが実行されるか確認
gcloud alpha run jobs execute ${NAME} \\
--region asia-northeast1
GCP の Cloud Run から作成したプロジェクトに遷移
URL を控えておく
#06. Cloud Scheduler で定期実行
以下を実行
PROJECT_NUMBER=$(gcloud projects list --filter="$(gcloud config get-value project)" --format="value(PROJECT_NUMBER)")
# 05. で控えた URL
CLOUD_RUN_URL="<https://(.*?)an.a.run.app>"
# 実行頻度
# 以下は 毎日 12:00 に slack に通知する
UNIX_CRON="0 12 * * *"
# 適当なサービスアカウント
SERVICE_ACCOUNT="<your accout>"
gcloud scheduler jobs create http ${NAME} \\
--location="asia-northeast1" \\
--schedule=${UNIX_CRON} \\
--uri=${CLOUD_RUN_URL} \\
--http-method="POST" \\
--time-zone="JST" \\
--oidc-service-account-email=${SERVICE_ACCOUNT}
GCP の Cloud Scheduler からジョブが作成されていることを確認する
実行頻度などを修正可能
References
HTTP ターゲットで認証を使用する - GCP docs
Cloud Run Jobsを使用してジョブをスケジュール実行する
https://tech.rhythm-corp.com/schedule-jobs-to-run-using-cloud-run-jobs/
unix cron について
cron ジョブ スケジュールの構成 - GCP docs
https://www.yoheim.net/blog.php?q=20190902
Comments