💚

Cloud Run JobsでBuildpacksを利用しDockerfile不要でGithub Actionsからデプロイする【GCP】

2024/03/05に公開

この記事について

GCPのCloud Run JobsでBuildpackを利用することにより、Dockerfile無しのソースコードだけで、Github Actionsからデプロイすることが可能です。

今回例で使うソースコードは、PythonでAPIを叩いてレスポンスを表示するだけのシンプルなコードを書きます、

概要

Cloud Runは、任意のプログラミング言語でコードを記述してコンテナイメージ化し、そのコンテナイメージを Google Cloud にデプロイするだけでアプリケーションを実行することができるGCPのフルマネージドサービスです。
なので基本的には自前でDockerfileを作成する必要があります。しかしBuildpackを用いることによりDockerfileを書かずに自動でソースコードを元にコンテナ化してくれます。なので、よりインフラの知識がなくとも気軽に実行環境を作ることができます。

想定する読者像

なんとなくCloud Runの概要を理解しているけど、動かしたことがない方がとりあえず動かしてみて動作を理解する手助けができればと思っています。
サービスとジョブの違いなど、Cloud Runの概要や細かい設定の解説は行いませんので、ご注意ください。

サンプルレポジトリ

この記事内で使用しているサンプルコードは下記リポジトリで管理しています。
https://github.com/bby-kanta/cloud_run_cd_sample

手順

https://cloud.google.com/run/docs/quickstarts/jobs/build-create-python?hl=ja
基本的には公式ドキュメントのクイックスタートを参考に進めていきます。

1. ソースコードを作成する

まずはPythonのスクリプト作っていきます。今回はAPIを叩いてレスポンスをログに表示するだけのシンプルな実装をしていきます。

https://fourtonfish.com/hellosalut?lang=ja
今回叩いてみるAPIのエンドポイントです。パラメータに言語を入れると、その国の挨拶が返ってきます。

{"code":"ja","hello":"こんにちは"}

実際に返ってくるレスポンスはこちらです。

ディレクトリを作成して、そのディレクトリに移動します。

$ mkdir cloud_run_cd_sample
$ cd cloud_run_cd_sample

さらにソースコードを置くディレクリを作成&移動しpython関連のファイルを作成。

$ mkdir cloudrun
$ cd cloudrun
$ touch {main.py,Procfile,requirements.txt}
cloudrun/main.py
import requests
import sys


HELLOSALUT_API_URL = "https://fourtonfish.com/hellosalut"

# Define main script
def main():
    """
    Hello, salut!のAPIを叩いてレスポンスをprintするだけ。
    ※ 国コードやグローバルIPからその地域の挨拶を返してくれるAPI
    """
    params = {
        "lang": "ja",
    } 

    response = requests.get(HELLOSALUT_API_URL, params=params)

    if response.status_code != 200:
        raise Exception("Request failed with status code: " + str(response.status_code))

    if response.status_code == 200:
        data = response.json()
        print(data)

if __name__ == "__main__":
    try:
        main()
    except Exception as err:
        message = (
            f"Task failed: {str(err)}"
        )
        print(message)
        sys.exit(1)
cloudrun/Procfile
web: python3 main.py
cloudrun/requirements.txt
requests==2.31.0

Buildpacksは自動でPythonアプリケーションであることを検出し、requirements.txtファイルからアプリケーションの依存関係を判断します。最後に、Procfileを参照してこのPythonサーバーの開始方法を判断します。

2.動作確認のため、一旦Github Actionsを使わずにCLIでデプロイする

もうこれだけで、Buildpacksを使えば、Cloud Runにデプロイすることができます。
CI/CDは環境変数の設定など、様々な要因でトラブることが多いので、一旦この記事の題名にもあるGithub ActionsでのCDはせずに、gcloud CLIを使ってお手軽にデプロイしてみます。gcloud CLIの設定をしていない方は下記を参考にインストールしてください。
※動作確認をする必要がない方はスキップしてください。
https://cloud.google.com/sdk/docs/install?hl=ja

gcloud CLIでCloud Runにデプロイする

gcloud run jobs deploy your-jobs-name \
    --source . \
    --tasks 1 \
    --max-retries 5 \
    --region asia-northeast1 \
    --project=【GCPのプロジェクト名】

最初に作成したディレクトリcloudrunをカレントディレクトリにした状態でコマンドを叩きます。
your-jobs-nameの部分はCloud Run Jobsの表示名です。ご自身で考えて入力してください。
--sourceソースコードのディレクトリのパスを指定します。
--tasksタスクを何個動かすかを数字で指定します。タスクを並列で実行したい場合などは2以上にします。
--max-retriesタスクが失敗したときに、リトライする回数を数字で指定します。
--regionデプロイするリージョンを指定します。

デプロイが成功した場合
デプロイに成功したらJob [your-jobs-name] has successfully been deployed.が出ます。

Google Cloud Consoleでデプロイできたか確認する

Google Cloud ConsoleでCloud Runのジョブを開きます。( https://console.cloud.google.com/run/jobs?hl=ja
先ほどデプロイしたyour-jobs-nameが存在しているので、デプロイが完了していることが確認できます。まだ、デプロイをしただけでジョブの実行はしていないので実行なしのステータスになっています。

実際にジョブを実行してAPIのレスポンスが返ってくるか確認する

your-jobs-nameをクリックしてジョブの詳細画面に入ります。
実行をクリックします。


履歴が追加されます。
次に実行IDをクリックします。


ログのタブをクリックします。
ログに {'code': 'ja', 'hello': 'こんにちは'}が表示されているので、期待通りの動作が確認できました。

デプロイからジョブの動作確認までできたので、Github ActionsからのCDをやっていきます。
ローカルマシンからソースコードをデプロイするのは便利ですが、最新の変更が反映できているか保証がないのでCDの設定するのがおすすめです。

3.Github Actionsでデプロイする

Github ActionsでCDの設定をします。具体的にはmainブランチにマージされたら、自動でソースコードからCloud Runのジョブにデプロイするようにします。

GithubからGCPへの認証方法は割愛

GithubからGCPへの認証を行わないといけませんが、認証の設定方法は長くなってしまうため、この記事では割愛させていただきます。
以下の記事がとても分かりやすく、かつトークンが不必要なOIDCでの認証を解説してくださっているので参考にしてみてください。
https://zenn.dev/kou_pg_0131/articles/gh-actions-oidc-gcp

サービスアカウントに必要な権限

トークン認証でも上述のOIDCでも、手順の中で適切なサービスアカウントを作成する必要があります。
以下Github Actionsからデプロイするにあたり、サービスアカウントに必要な権限です(ドキュメントはこちら)。
サービスアカウントを作成したら、Github Actionsに使用するのでサービスアカウントのemailを控えておいてください。

  • Artifact Registry Writer
  • Cloud Build Editor
  • Cloud Run Developer
  • Service Account User
  • Storage Admin

Github Actionsの設定方法

プロジェクトのルートディレクトリ(この記事ではcloud_run_cd_sample)に戻りファイルを作成します。

mkdir .github
mkdir .github/workflows
touch .github/workflows/cloud-run-jobs-build.yml

Githubのレポジトリに環境変数を追加してください。

  • GCS_PROJECT_ID
    • あなたのGCPのプロジェクトのID
  • GCS_WIP
    • Github用に作成した、Workload Identity プールの情報を入力する
    • projects/<プロジェクト番号>/locations/global/workloadIdentityPools/<プールID>/providers/<プロバイダID>
  • GCS_SERVICE_ACCOUNT_EMAIL
    • Github用に作成した、サービスアカウントのemail
.github/workflows/cloud-run-jobs-build.yml
name: Deploy to Cloud Run Job

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - uses: google-github-actions/auth@v2
        with:
          project_id: "${{ vars.GCS_PROJECT_ID }}"
          workload_identity_provider: "${{ vars.GCS_WIP }}"
          service_account: "${{ vars.GCS_SERVICE_ACCOUNT_EMAIL }}"

      - name: Setup Google Cloud
        uses: google-github-actions/setup-gcloud@v2
        with:
          project_id: ${{ vars.GCS_PROJECT_ID }}

      - name: Cloud Run Jobs Deploy
        run: |
          gcloud run jobs deploy your_job_name \
            --source ./cloudrun \
            --tasks 1 \
            --max-retries 5 \
            --region asia-northeast1 \
            --project ${{ vars.GCS_PROJECT_ID }}
  - uses: google-github-actions/auth@v2
    with:
      project_id: "${{ vars.GCS_PROJECT_ID }}"
      workload_identity_provider: "${{ vars.GCS_WIP }}"
      service_account: "${{ vars.GCS_SERVICE_ACCOUNT_EMAIL }}"

Github ActionsからGCPに認証をかけている部分です。
google-github-actions/authを使って認証をしましょう。

  - name: Setup Google Cloud
    uses: google-github-actions/setup-gcloud@v2
    with:
      project_id: ${{ vars.GCS_PROJECT_ID }}

この部分でgcloudコマンドを使えるようにします。

  - name: Cloud Run Jobs Deploy
    run: |
      gcloud run jobs deploy your-job-name \
        --source ./cloudrun \
        --tasks 1 \
        --max-retries 5 \
        --region asia-northeast1 \
        --project ${{ vars.GCS_PROJECT_ID }}

実際にソースコードをデプロイしている部分です。
【gcloud CLIでCloud Runにデプロイする】で叩いたコマンドと一緒です。

これでメインにマージしたら、自動でソースコードからデプロイするようになりました。

参考にした記事

https://cloud.google.com/blog/ja/products/serverless/build-and-deploy-an-app-to-cloud-run-with-a-single-command
https://dev.classmethod.jp/articles/google-cloud-buildpacks/

Discussion