【Cloud Run】コンテナを稼働させるまでに必要なgcloudコマンドをシェル関数化する

Code

はじまり

リサちゃん
リサちゃん

あー、またデプロイし直さなければ・・・

135ml
135ml

関数にしてしまおう。

Cloud Run用のgcloudコマンドをまとめる

Google Cloudのサービスの一つであるCloud Runは、コンテナをサーバーレスで実行できる便利なサービスです。しかし、コンテナのデプロイや環境変数の設定など、繰り返し行う操作が多く、毎回長いgcloudコマンドを入力するのは面倒です。

そこで今回は、よく使うgcloudコマンドをシェル関数化して、作業を効率化する方法を紹介します。具体的には以下の2つの関数を実装します。

  1. deploy_cloud_run_container – Cloud Runにコンテナをデプロイするための関数
  2. update_env_for_cloud_run_service – Cloud Runサービスの環境変数を更新するための関数

これらの関数を一度作ってしまえば、長いgcloudコマンドを作り直す必要がなくなり、引数のバリデーションやエラーハンドリングも自動化できます。さらに、Discordへの通知機能も組み込むことで、長時間掛かるデプロイ作業の完了を通知してくれます。

前提条件

この記事の内容を実践するには、以下の環境が必要です。

  • Google Cloud SDKがインストールされていること
  • Google Cloudアカウントとプロジェクトが設定済みであること
  • bashまたはzshなどのシェル環境
  • (オプション)Discordの通知を受け取るための設定

Cloud Runコンテナをデプロイするシェル関数

まずは、Cloud Runにコンテナをデプロイするための関数deploy_cloud_run_containerを見ていきましょう。

function deploy_cloud_run_container() {
  local FUNC_NAME="${FUNCNAME[0]}"
  send_discord_notification "コンテナをデプロイするよ!"

  # --help オプションのチェック
  for arg in "$@"; do
    if [ "$arg" = "--help" ]; then
      echo "[INFO] ${FUNC_NAME}: Usage: ${FUNC_NAME} IMAGE_NAME PROJECT_ID [REGION]"
      echo "  IMAGE_NAME : デプロイする Cloud Run サービスの名前"
      echo "  PROJECT_ID : 対象の GCP プロジェクトID"
      echo "  REGION     : リージョンのサフィックス (例: 'central1' → us-central1, デフォルト: central1)"
      echo "  TIMEOUT    : value for timeout (例: '40m', '1m32s' and so on. '40m' as a default.)"
      echo "  SERVICE_ACCOUNT: サービスアカウントのメールアドレス (例: my-service-account@my-project.iam.gserviceaccount.com)"
      echo "[INFO] ${FUNC_NAME}: Notice: API reference URL: <https://cloud.google.com/sdk/gcloud/reference/run/deploy>"
      return 0
    fi
  done

  # 引数チェック: IMAGE_NAME と PROJECT_ID は必須
  if [ $# -lt 2 ]; then
    echo "[ERROR] ${FUNC_NAME}: Usage: ${FUNC_NAME} IMAGE_NAME PROJECT_ID [REGION]" >&2
    return 1
  fi

  # 引数チェック: IMAGE_NAME と PROJECT_ID は必須。最大5個の引数を許容。
  if [ "$#" -lt 2 ] || [ "$#" -gt 5 ]; then
    echo "[ERROR] ${FUNC_NAME}: Usage: ${FUNC_NAME} IMAGE_NAME PROJECT_ID [REGION] [TIMEOUT] [SERVICE_ACCOUNT]" >&2
    return 1
  fi

  # パラメータの設定
  local image_name="$1"
  local project_id="$2"
  local full_region="${3:us-central1}"
  local timeout="${4:-40m}"
  local service_account="${5:-}"

  # gcloud コマンドの存在確認
  if ! command -v gcloud >/dev/null 2>&1; then
    echo "[ERROR] ${FUNC_NAME}: gcloud コマンドが見つかりません。Google Cloud SDK のインストールを確認してください。" >&2
    return 1
  fi

  # Dockerfile の存在チェック
  if [ ! -f "./Dockerfile" ]; then
    echo "[ERROR] ${FUNC_NAME}: 現在のディレクトリに Dockerfile が見つかりません。" >&2
    return 1
  fi

  # Cloud Run サービスのデプロイ処理
  local cmd=( "gcloud" "run" "deploy" "$image_name" "--source" "." "--project=${project_id}" "--region=${full_region}" "--allow-unauthenticated" "--timeout=${timeout}" )
  if [ -n "${service_account}" ]; then
    cmd+=( "--service-account=${service_account}" )
  fi
  echo "cmd is here: ${cmd[*]}"

  echo "[INFO] ${FUNC_NAME}: Running command: ${cmd[*]}"
  echo ""
  echo "======= Deployments on Google Cloud ========================================================================"
  if ! "${cmd[@]}"; then
    send_discord_notification_about_gcloud_run "失敗…" "コンテナをデプロイできなかったよ…" "red"
    echo "[ERROR] ${FUNC_NAME}: Cloud Run サービス '$image_name' のデプロイに失敗しました。" >&2
    return 1
  fi
  echo "============================================================================================================"
  echo ""

  send_discord_notification_about_gcloud_run "デプロイしたよ!" "コンテナをデプロイしたよ!" "green"
}

この関数は以下のような特徴を持っています。

1. ヘルプ機能

--helpオプションを指定すると、関数の使い方が表示されます。これにより、関数の使い方を忘れても簡単に確認できます。

2. 引数のバリデーション

必須引数(イメージ名とプロジェクトID)が指定されているかチェックし、引数の数が適切な範囲内かも確認します。これにより、誤った使い方を防止できます。

3. 環境チェック

gcloudコマンドが利用可能かどうか、現在のディレクトリにDockerfileが存在するかどうかをチェックします。これにより、デプロイ前に必要な条件が揃っているか確認できます。

4. 柔軟なパラメータ設定

リージョン、タイムアウト、サービスアカウントなどのオプションパラメータにデフォルト値を設定しつつ、必要に応じてカスタマイズできるようになっています。

5. Discord通知機能

デプロイの開始時と完了時(成功/失敗)にDiscordに通知を送信します。これにより、長時間かかるデプロイ作業の状況を離れた場所からでも確認できます。

Cloud Runサービスの環境変数を更新するシェル関数

次に、Cloud Runサービスの環境変数を更新するための関数update_env_for_cloud_run_serviceを見ていきましょう。

function update_env_for_cloud_run_service() {
  # ローカル変数に関数名を設定
  local FUNC_NAME="${FUNCNAME[0]}"
  send_discord_notification "サービスの環境変数を更新するよ!"

  # --help オプションが指定された場合、利用方法を表示して終了
  if [[ "$1" == "--help" ]]; then
    echo "[INFO] ${FUNC_NAME}: Usage: ${FUNC_NAME} -n SERVICE_NAME -p PROJECT -r REGION -f FILE_PATH"
    echo "[INFO] ${FUNC_NAME}: Example: ${FUNC_NAME} -s my-service -p project_id -r us-central1 -f env.yml"
    echo "[INFO] ${FUNC_NAME}:"
    echo "[INFO] ${FUNC_NAME}: Notice: API reference URL: <https://cloud.google.com/sdk/gcloud/reference/run/services/update>"
    return 0
  fi

  # 必要な変数の初期化
  local service=""
  local project=""
  local region=""
  local file_path="env.yml"

  # 引数の解析
  while [[ $# -gt 0 ]]; do
    case "$1" in
      -n|--service)
        service="$2"
        shift 2
        ;;
      -p|--project)
        project="$2"
        shift 2
        ;;
      -r|--region)
        region="$2"
        shift 2
        ;;
      -f|--file)
        file_path="$2"
        shift 2
        ;;
      --help)
        echo "[INFO] ${FUNC_NAME}: Usage: ${FUNC_NAME} -n SERVICE_NAME -p PROJECT -r REGION -f FILE_PATH"
        echo "[INFO] ${FUNC_NAME}: Example: ${FUNC_NAME} -s my-service -p project_id -r us-central1 -f env.yml"
        return 0
        ;;
      *)
        echo "[ERROR] ${FUNC_NAME}: Unknown parameter: $1"
        echo "[INFO] ${FUNC_NAME}: Usage: ${FUNC_NAME} -n SERVICE_NAME -p PROJECT -r REGION -f FILE_PATH"
        return 1
        ;;
    esac
  done

  # 必須パラメータのチェック
  if [[ -z "$service" || -z "$project" || -z "$region" ]]; then
    echo "[ERROR] ${FUNC_NAME}: Missing required parameter(s)."
    echo "[INFO] ${FUNC_NAME}: Usage: ${FUNC_NAME} -n SERVICE_NAME -p PROJECT -r REGION -f FILE_PATH"
    return 1
  fi

  # file_path の存在チェック
  if [ ! -f "./$file_path" ]; then
    echo "[Error] ${FUNC_NAME}: Error: 現在のディレクトリに ${file_path} が見つかりません。" >&2
    return 1
  fi

  # gcloud コマンドの実行
  echo "[INFO] ${FUNC_NAME}: Updating service '${service}' with environment variables from file '${file_path}'..."
  echo ""
  echo "======= Deployments on Google Cloud ========================================================================"
  gcloud run services update "$service" \\\\
    --project "$project" \\\\
    --region "$region" \\\\
    --env-vars-file="$file_path";
  echo "============================================================================================================"
  echo ""
  local ret_code=$?

  if [[ $ret_code -eq 0 ]]; then
    send_discord_notification_about_gcloud_run "更新したよ!" "サービスの環境変数を更新したよ!" "green"
    echo "[INFO] ${FUNC_NAME}: Service '${service}' updated successfully."
  else
    send_discord_notification_about_gcloud_run "失敗…" "サービスの環境変数を更新できなかったよ…" "red"
    echo "[ERROR] ${FUNC_NAME}: Failed to update service '${service}'."
    return $ret_code
  fi
}

この関数は以下のような特徴を持っています。

1. 名前付き引数のサポート

-n, -p, -r, -fなどの名前付き引数を使用することで、引数の順序を気にせずに使用できます。これにより、関数の使い勝手が向上します。

2. ヘルプ機能

--helpオプションを指定すると、関数の使い方と例が表示されます。

3. 引数のバリデーション

必須パラメータ(サービス名、プロジェクトID、リージョン)が指定されているかチェックします。

4. ファイルの存在チェック

環境変数ファイルが存在するかどうかをチェックします。これにより、ファイルが見つからない場合のエラーを事前に防止できます。

5. Discord通知機能

環境変数の更新開始時と完了時(成功/失敗)にDiscordに通知を送信します。

使用例

これらの関数を実際に使用する例を見てみましょう。

deploy_cloud_run_containerの使用例

# 基本的な使用方法
deploy_cloud_run_container "test-container" "test-project" "us-central1"

# タイムアウトとサービスアカウントを指定する場合
deploy_cloud_run_container "test-container" "test-project" "us-central1" "60m" "service-account@test-project.iam.gserviceaccount.com"

# ヘルプを表示
deploy_cloud_run_container --help

update_env_for_cloud_run_serviceの使用例

# 基本的な使用方法
update_env_for_cloud_run_service -n "test-container" -p "test-project" -r "us-central1"

# 環境変数ファイルを指定する場合
update_env_for_cloud_run_service -n "test-container" -p "test-project" -r "us-central1" -f "custom-env.yml"

# ヘルプを表示
update_env_for_cloud_run_service --help

環境変数ファイルの形式

update_env_for_cloud_run_service関数で使用する環境変数ファイルは、YAMLフォーマットで記述します。以下は例です。

API_KEY: "your-api-key"
DEBUG_MODE: "true"
DATABASE_URL: "postgresql://user:password@host:port/dbname"

このファイルをデフォルトではenv.ymlという名前で保存し、関数実行時に-fオプションで別のファイル名を指定することもできます。

関数の改善ポイント

これらの関数はすでに便利ですが、さらに以下のような改善ができます。

1. エラーハンドリングの強化

現在もエラーチェックは行っていますが、より詳細なエラーメッセージを表示したり、特定のエラーに対して自動的に対処する機能を追加できます。

2. ログ機能の拡張

現在はコンソールに情報を出力していますが、ログファイルに記録する機能を追加すると、過去のデプロイ履歴を確認しやすくなります。

3. 並列デプロイのサポート

複数のサービスを同時にデプロイする機能を追加すると、大規模なシステムのデプロイ時間を短縮できます。

まとめ

この記事では、Cloud Runでコンテナを稼働させるために必要なgcloudコマンドをシェル関数化する方法を紹介しました。

deploy_cloud_run_container関数とupdate_env_for_cloud_run_service関数を使うことで、以下のメリットが得られます。

  • 使い回すことが出来る
  • 引数のバリデーションやエラーハンドリングが自動化される
  • Discordへの通知機能により、デプロイ状況を離れた場所からでも確認できる
  • ヘルプ機能により、gcloudコマンドや関数の使い方を簡単に確認できる

これらの関数を自分の環境に合わせてカスタマイズし、日々のCloud Run操作を効率化することが出来るかもしれませんね。

おしまい

リサちゃん
リサちゃん

助かる

135ml
135ml

他のコマンドもまとめてしまいたいな。

以上になります!

コメント

タイトルとURLをコピーしました