Cloud Ace Tech Blog
🌱

【初学者向け】予算アラートを自動設定するシェルスクリプトを作ってみた

はじめに

クラウドエース第三開発部に所属している柴田です。この記事では「 Google Cloud の予算アラートを自動設定するシェルスクリプト」の作成手順について紹介します。ほぼ IT 未経験で新卒入社した私でも Google Cloud 公式ドキュメントを活用することで簡単に作成できたので、初学者の方にも分かりやすいように解説していけたらと思います。

対象読者とゴール

対象読者

  • Google Cloud 初学者(Google Cloud でプロジェクトを作成できるレベルを想定)
  • シェルスクリプト初学者
  • Google Cloud 予算アラートを自動設定したい方

ゴール

  • Google Cloud 初学者でも予算アラートを自動で設定するシェルスクリプトを作成できるようになる

準備編

シェルスクリプトについて

シェルスクリプトがよく分からないという方へ向けて、概要とファイルの作成手順について説明します。簡単な説明になっているので、より詳しく知りたい方はこの機会に調べてみてください。

シェルスクリプトとは

シェルスクリプトとは、コンピュータに一連の指示(コマンド)を自動で実行させるために書かれたプログラムの一種です。「シェル」というのは、コンピュータと私たちをつなぐ役割をするプログラムのことです。普段ターミナルで使うコマンドも、このシェルを通じてコンピュータに指示を送っています。
例えば、毎日決まった時間にファイルを整理したり、バックアップを取ったりする作業を、シェルスクリプトを使えば自動化できます。これによって、面倒な手作業を減らし、効率よく作業を進められるようになります。
なお、本記事では、シェルスクリプトを Bash で実行することを前提としています。

ファイルの作成

PC ローカルで以下のコマンドを実行します。
本記事では予算アラートを作成するシェルスクリプトだと分かるように、ファイル名は budget_alert にしましょう。

$ touch budget_alert.sh

これで空のファイルが作成できました!
このファイルに内容を記述していきましょう。

シェルスクリプトで Hello, World! を表示してみよう。

初めてシェルスクリプトを作成する方はシンプルなスクリプトから始めてみましょう。

  1. touch コマンドを使って hello.sh という空のファイルを作成
$ touch hello.sh
  1. nano コマンドでスクリプトを編集
    今回は Mac を用いたコマンドで紹介していきます。
    Windows などを使用する場合は対応するコマンドを調べて実行してください。
$ nano hello.sh
  1. 以下のコードを記述
hello.sh
#!/bin/bash 
echo "Hello, World!"
  1. 保存
    Ctrl + O(保存)→ Enter → Ctrl + X(終了)で保存します。
  2. 実行権限の付与
    実行ファイルに権限を付与します。
    コマンドの細かい説明についてはここで解説しないため、詳細は調べてください。
$ chmod +x hello.sh
  1. 実行
    以下のコマンドを実行して…
$ ./hello.sh

以下の出力がされたら OK です!

Hello, World!

必要なもの

Google Cloud プロジェクトの作成

大前提として、まずはプロジェクトを作成しておきましょう。
https://cloud.google.com/resource-manager/docs/creating-managing-projects?hl=ja#creating_a_project

gcloud CLI のセットアップ

  1. 今回の作業環境である PC ローカルに gcloud CLI をインストールしましょう。
    以下のドキュメントを参考に gcloud CLI の最新バージョンをインストールしてください。
    https://cloud.google.com/sdk/docs/install-sdk?hl=ja

  2. インストールの確認
    以下のコマンドを実行し、以下のようにバージョンが表示されれば OK です。

$ gcloud version
 Google Cloud SDK 506.0.0

権限の確認

後述しますが、今回はプロジェクトオーナー宛に通知を送るという要件のため、自分がプロジェクトオーナーであるかを IAM で確認しましょう。

IAM について

Google Cloud の IAM とは、Google Cloud のリソースに対するアクセス管理を行う仕組みです。
IAM を使うことで、誰が何のリソースに対してどのようなアクセス権限を持つかを定義することでアクセス制御を管理します。
https://cloud.google.com/iam/docs/overview?hl=ja

プロジェクトオーナーについて

Google Cloud のプロジェクトオーナーとは、プロジェクト単位でほとんどのリソースを操作できる強力な権限を持つロールです。正式なロール名は roles/owner です。
https://cloud.google.com/iam/docs/roles-overview?hl=ja#basic

予算アラートについて

そもそも予算アラートって何?なんで必要なの?という方に向けて簡単に説明します。

予算とアラートとは?

Google Cloud における「予算とアラート」は、Cloud Billing の機能の一つです。
この機能を使用すると、プロジェクトや請求先アカウント内の費用を追跡し、設定した予算を超えた際に、課金管理者やユーザーに通知を送ることができます。

ただし、費用の記録には最大 24 時間の遅延があるため、アラートが発報された時点では、すでにさらに費用が発生している可能性があります。そのため、予算を低めに設定し、余裕を持たせ、想定以上の費用が発生するリスクを抑えることが推奨されています。
https://cloud.google.com/billing/docs/how-to/budgets?hl=ja

Cloud Billing について

Cloud Billing は、Google Cloud 利用料金を確認できるサービスです。
「予算とアラート」以外に、「レポート」や「課金データのエクスポート」などの機能があります。
https://cloud.google.com/billing/docs/concepts?hl=ja

請求先アカウントについて

請求先アカウントとは、Google Cloud のリソースの使用料金を管理し、支払いを行うためのアカウントです。
https://cloud.google.com/billing/docs/how-to/manage-billing-account?hl=ja#overview

予算を設定するメリット

Google Cloud は従量課金制のため、予期せぬ高額な料金が発生することがあります。私も過去にプロジェクトの料金を気にせず使用していた結果、予想以上の金額になっていたという経験があります…。毎回 Google Cloud コンソールに料金を確認しに行くのは手間がかかりますが、予算アラートを設定しておけば、メールで通知を受け取り、料金超過のリスクを減らせます。

予算をGoogle Cloud コンソールで作成する方法

Google Cloud コンソールで予算アラートを設定する方法も紹介します。コマンドだとイメージが湧かない、という方は先に GUI で作成してイメージしておくと良いかもしれません。

  1. ダッシュボード>「請求の詳細を表示」

  2. 機能の中から「予算とアラート」を選択

  3. 「予算を作成」を選択

  4. 範囲を設定
    名前や期間、特定のプロジェクトに絞り込みなどが出来ます。
    今回はシェルスクリプトで作成する予算アラートと同じ設定になるように選択します。

  5. 金額を設定

  6. 操作
    予算の割合や通知先を管理することが出来ます。
    自分がプロジェクトオーナーである場合は、メール通知アラートをプロジェクトオーナーに送信するを選択しておくと自分のメールに通知がきます。

  7. 作成

実践編

ここから実際にシェルスクリプトを作成していきます。

作成する

要件

  1. 実行内容
    • bash budget_alert.sh を実行したら、以下の条件で予算アラートが設定される
  2. 入力
    • プロジェクト ID のみ
  3. エラー時の挙動
    • 予算アラートを設定できなかったら、その旨を伝える標準出力をする
  4. 以下の条件で設定する
    • 予算: 3 万円
    • 期間:月別
    • 予算の割合: 50%、75%、90%
    • 通知の管理:メール通知アラートをプロジェクト オーナーに送信する

作成手順

ここから、先ほど作成した budget_alert.sh に処理を記述していきます。

  1. プロジェクト ID の取得

まずはプロジェクト ID を入力してもらう仕組みから作ります。

budget_alert.sh
# プロジェクトID取得
echo "Google Cloud プロジェクト ID を入力してください:"
read PROJECT_ID
詳細
  • echo
    メッセージを表示
  • read
    入力を受け取ってそれを変数(今回は PROJECT_ID)に格納する
  1. 請求先アカウントの取得

取得したプロジェクト ID に紐づく課金アカウントを取得するコマンドを記述します。
その時に使用する β 版をインストールするスクリプトも追加します。
ついでに、請求先アカウントが取得できなかった場合のエラーメッセージも追加しましょう。

budget_alert.sh
# β 版インストール
gcloud components install beta

# プロジェクト ID から請求先アカウント ID を取得
BILLING_ACCOUNT_ID=$(gcloud beta billing projects describe $PROJECT_ID --format="value(billingAccountName)" | cut -d'/' -f2)

# 請求先アカウントが取得できなかった場合にメッセージを表示
if [ -z "$BILLING_ACCOUNT_ID" ]; then
 echo "プロジェクト ID が正しいか、請求先アカウントがリンクされているか確認してください。"
 exit 1
fi
詳細
  • gcloud components install beta
    Google Cloud CLI の β 版機能を有効化
  • gcloud beta billing projects describe
    プロジェクトの課金情報を取得
  • --format="value(billingAccountName)"
    必要な値(請求先アカウント名)のみ取得する
  • cut -d'/' -f2
    結果の「/」で区切られた部分から 2 番目(アカウント ID 部分)を抜き出す
  • [ -z "$BILLING_ACCOUNT_ID" ]
    BILLING_ACCOUNT_ID が空かどうか確認する
  1. 予算アラート API の有効化

今回は API を使って予算アラートを設定します。
そのため、必要な API を有効化するコマンドを記述します。

budget_alert.sh
# API 有効化
gcloud services enable billingbudgets.googleapis.com --project=$PROJECT_ID
詳細
  • gcloud services enable
    指定した API を有効化
  • billingbudgets.googleapis.com
    今回使用する予算関連の API
API を使う理由

gcloud を使って、予算アラートを作成することも可能です。ただし、「メール通知アラートをプロジェクトオーナーに送信する」という要件を gcloud では満たせないため、API を使用しました。

  1. JSON リクエストの作成

ここから予算アラート設定を行うスクリプトを書いていきます。
API を使って予算アラートを設定すると言ったものの、どうやって書いたら良いのか分からない…という方もいるかと思います。そういう時には、公式ドキュメントを活用してみてください。
「Google Cloud 予算アラート API」などと検索すると Cloud Billing Budget API を使ってみるというドキュメントが出てくると思います。このドキュメントの「API の使用」に、ユーザーガイド( Cloud Billing Budget API の使用)が載っています。
更にその中の「予算の作成」に以下の JSON リクエストのサンプルが記載されています。

{
  "displayName": "Keep my spending down",
  "budgetFilter": {
    "projects": [
      "projects/budget-scope-project-id"
    ],
    "calendar_period": "QUARTER"
  },
  "amount": {
    "lastPeriodAmount": {}
  },
  "thresholdRules": {
    "thresholdPercent": 0.8,
    "spendBasis": "CURRENT_SPEND"
  }
}

API へリクエストを送る際のさまざまなパラメータは、JSON ファイルに記述して指定する必要があります。そのため、JSON ファイルを作成します。
ただし、このサンプルの中身だけでは、詳細な設定が出来ません。
そこで、ドキュメントの REST Resource: billingAccounts.budgets を参考に、設定に必要な箇所を探して追加します。予算額など、今後変更する可能性がある箇所については変数に格納しておくと良いかもしれません。さらに、JSON ファイルを作成する際に、既存の JSON ファイル名と被らないように工夫をしておくと良いです。

budget_alert.sh
# 固定値設定
CALENDAR_PERIOD="MONTH"
AMOUNT_CURRENCY="JPY"
AMOUNT_UNITS="30000"

# リクエストの JSON を生成
REQUEST_FILE="${PROJECT_ID}_request.json"
cat <<EOF > $REQUEST_FILE
{
 "displayName": "${PROJECT_ID}_budget_alert",
 "budgetFilter": {
  "projects": [
   "projects/$PROJECT_ID"
  ],
  "calendarPeriod": "$CALENDAR_PERIOD"
 },
 "amount": {
  "specifiedAmount": {
   "currencyCode": "$AMOUNT_CURRENCY",
   "units": "$AMOUNT_UNITS"
  }
 },
 "thresholdRules": [
  {
   "thresholdPercent": 0.5,
   "spendBasis": "CURRENT_SPEND"
  },
  {
   "thresholdPercent": 0.75,
   "spendBasis": "CURRENT_SPEND"
  },
  {
   "thresholdPercent": 0.9,
   "spendBasis": "CURRENT_SPEND"
  }
 ],
 "notificationsRule": {
  "disableDefaultIamRecipients": true,
  "enableProjectLevelRecipients": true
 }
}
EOF
詳細
  1. 固定値の設定
  • CALENDAR_PERIOD="MONTH"
    デフォルトの期間を月単位として変数定義
  • AMOUNT_CURRENCY="JPY"
    日本円をデフォルト値として変数定義
  • AMOUNT_UNITS="30000"
    デフォルトの予算額を 3 万円として変数定義
  1. JSONファイルの設定
    一時的に JSON ファイルを作成してそこに JSON リクエストを書き込みます。
  • REQUEST_FILE="${PROJECT_ID}_request.json"
    JSON ファイル名の文字列を生成し、変数に定義
  • cat <<EOF > $REQUEST_FILE
    ここから EOF までの内容をファイルに書き込む
  1. 設定内容の記述
    ※詳しくは公式ドキュメントを参照してください。
  • "displayName": "${PROJECT_ID}_budget_alert"
    予算アラート名を設定
  • "projects": ["projects/$PROJECT_ID"]
    予算を入力したプロジェクトのみに限定する
  • "calendarPeriod": "$CALENDAR_PERIOD"
    期間を CALENDER_PERIOD に定義した単位に設定
  • "currencyCode": "$AMOUNT_CURRENCY"
    通貨コードを AMOUNT_CURRENCY に定義したコードに設定
  • "units": "$AMOUNT_UNITS"
    予算として使用する指定金額を AMOUNT_UNIT に定義した 3 万円に設定
  • "thresholdPercent": 0.5
    閾値を設定 ( 0.5 = 50 % )
  • "disableDefaultIamRecipients": true
    閾値を超えたときに送信されるデフォルトの通知を無効化
    (デフォルトの通知は、対象アカウントの請求先アカウント管理者および請求先アカウントユーザーの IAM ロールを持つユーザーに送信される)
  • "enableProjectLevelRecipients": true
    「プロジェクトオーナーにメール通知を送信する」を有効化
  1. アクセストークンの取得

API へのリクエストには認証情報が必要です。今回は認証情報の一つであるアクセストークンを取得し、使用します。取得できない場合は標準出力でエラーを通知します。

budget_alert.sh
ACCESS_TOKEN=$(gcloud auth print-access-token)
if [ -z "$ACCESS_TOKEN" ]; then
 echo "アクセストークンを取得できませんでした。"
 exit 1
fi
詳細
  • gcloud auth print-access-token
    Google Cloud のアクセストークンを取得します。
  1. API の呼び出し

次に、API の呼び出しを行います。
ついでに、予算アラートがきちんと作成されたかどうかのエラー判定も行いましょう。

budget_alert.sh
# cURL コマンドで API を呼び出し
echo "Cloud Billing 予算を作成中..."
RESPONSE=$(curl -s -X POST \
 -H "Authorization: Bearer $ACCESS_TOKEN" \
 -H "x-goog-user-project: $PROJECT_ID" \
 -H "Content-Type: application/json; charset=utf-8" \
 -d @$REQUEST_FILE \
 "https://billingbudgets.googleapis.com/v1/billingAccounts/$BILLING_ACCOUNT_ID/budgets")

# エラーの判定
ERROR_CODE=$(echo "$RESPONSE" | grep -o '"code": [0-9]*' | cut -d: -f2 | tr -d ' ')
if [ -n "$ERROR_CODE" ]; then
 echo "エラーが発生しました: $RESPONSE"
 exit 1
else  
 echo "Cloud Billing 予算の作成が完了しました!"
fi
詳細
  1. API の呼び出し
  1. エラーの確認
  • grep -o
    レスポンス内のエラーコード部分を抽出
  • cut -d: -f2
    コード番号を取得
  • tr -d ' '
    余分なスペースを削除
  1. 作業ファイルの削除
    作成した JSON ファイルはもう必要ないので、自動的に削除するようにしましょう。
budget_alert.sh
rm $REQUEST_FILE
詳細
  • rm
    ファイルを削除

シェルスクリプトの完成です!

完成品

budget_alert.sh
#!/bin/bash

# β 版インストール
gcloud components install beta

# プロジェクト ID 取得
echo "Google Cloud プロジェクト ID を入力してください:"
read PROJECT_ID

# プロジェクト ID から請求先アカウント ID を取得
BILLING_ACCOUNT_ID=$(gcloud beta billing projects describe $PROJECT_ID --format="value(billingAccountName)" | cut -d'/' -f2)

if [ -z "$BILLING_ACCOUNT_ID" ]; then
 echo "プロジェクト ID が正しいか、課金アカウントがリンクされているか確認してください。"
 exit 1
fi

# API 有効化
gcloud services enable billingbudgets.googleapis.com --project=$PROJECT_ID

# 固定値設定
CALENDAR_PERIOD="MONTH"
AMOUNT_CURRENCY="JPY"
AMOUNT_UNITS="30000"

REQUEST_FILE="${PROJECT_ID}_request.json"

# リクエストの JSON を生成
cat <<EOF > $REQUEST_FILE
{
 "displayName": "${PROJECT_ID}_budget_alert",
 "budgetFilter": {
  "projects": [
   "projects/$PROJECT_ID"
  ],
  "calendarPeriod": "$CALENDAR_PERIOD"
 },
 "amount": {
  "specifiedAmount": {
   "currencyCode": "$AMOUNT_CURRENCY",
   "units": "$AMOUNT_UNITS"
  }
 },
 "thresholdRules": [
  {
   "thresholdPercent": 0.5,
   "spendBasis": "CURRENT_SPEND"
  },
  {
   "thresholdPercent": 0.75,
   "spendBasis": "CURRENT_SPEND"
  },
  {
   "thresholdPercent": 0.9,
   "spendBasis": "CURRENT_SPEND"
  }
 ],
 "notificationsRule": {
  "disableDefaultIamRecipients": true,
  "enableProjectLevelRecipients": true
 }
}
EOF

# アクセストークンの取得
ACCESS_TOKEN=$(gcloud auth print-access-token)
if [ -z "$ACCESS_TOKEN" ]; then
 echo "アクセストークンを取得できませんでした。"
 exit 1
fi
   
# cURL コマンドで API を呼び出し
echo "Cloud Billing 予算を作成中..."
RESPONSE=$(curl -s -X POST \
 -H "Authorization: Bearer $ACCESS_TOKEN" \
 -H "x-goog-user-project: $PROJECT_ID" \
 -H "Content-Type: application/json; charset=utf-8" \
 -d @$REQUEST_FILE \
 "https://billingbudgets.googleapis.com/v1/billingAccounts/$BILLING_ACCOUNT_ID/budgets")
    
# エラーの判定
ERROR_CODE=$(echo "$RESPONSE" | grep -o '"code": [0-9]*' | cut -d: -f2 | tr -d ' ')
if [ -n "$ERROR_CODE" ]; then
 echo "エラーが発生しました: $RESPONSE"
 exit 1
else  
 echo "Cloud Billing 予算の作成が完了しました!"
fi
    
# 作業ファイルを削除
rm $REQUEST_FILE

実行

作成したシェルスクリプトを実行してみましょう。
以下のように「Cloud Billing 予算の作成が完了しました!」と表示されるはずです。

$./budget_alert.sh 
Google Cloud プロジェクト ID を入力してください:
project_id 

All components are up to date.
Cloud Billing 予算を作成中...
Cloud Billing 予算の作成が完了しました!

また、実際に作成できているか確認してください。
Google Cloud コンソールで、以下のように予算アラートが作成されていたら成功です。

おわりに

いかがでしたでしょうか。
今回は予算アラートを設定しましたが、Google Cloud 公式ドキュメントを参考にすれば他の機能に応用することも出来ますので、色々と試してみてください!

Cloud Ace Tech Blog
Cloud Ace Tech Blog

Discussion