🌟

github actionsでcloud run jobsへデプロイする

2023/12/10に公開

はじめに

cloud runのサービスの記事はあったのですが、jobsをgithub actionsでデプロイする関連の記事がなかなか見当たらなかったので残します。

cloud run jobs

Cloud Run サービスはNextJSとかのプロジェクトをおいておいて、webアプリやAPIの公開ができるものですが、Cloud Run ジョブはバッチ処理などのタスクを実行できます。
dockerイメージを置いておき、日時指定で実行できます。cloud functionsと同じような用途で、より設定が柔軟に可能なイメージが近いと思います。

https://zenn.dev/google_cloud_jp/articles/cloudrun-jobs-basic

github actions

以下全文です。

.github/workflows/deploy.yml
name: Deploy to Cloud Run

on:
  push:
    branches:
      - master
env:
  SERVICE_NAME: ${{ secrets.SERVICE_NAME }}
  SERVICE_ACCOUNT_NAME: ${{ secrets.SERVICE_ACCOUNT_NAME }}
  GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
  GCP_REGION: ${{ secrets.GCP_REGION }}
  IMAGE: ${{ secrets.GCP_REGION }}-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.SERVICE_NAME }}/${{ secrets.SERVICE_NAME }}

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - id: "auth"
      uses: "google-github-actions/auth@v2"
      with:
        credentials_json: "${{ secrets.GCP_SA_KEY }}"

    - name: Configure docker to use the gcloud cli
      run: gcloud auth configure-docker ${{ secrets.GCP_REGION }}-docker.pkg.dev --quiet

    - name: Delete old image
      continue-on-error: true
      run: gcloud artifacts docker images delete ${{ env.IMAGE }} --quiet

    - name: Build a docker image
      run: docker build -t ${{ env.IMAGE }} .

    - name: Push the docker image
      run: docker push ${{ env.IMAGE }}

    - name: Deploy to Cloud Run
      run: | 
        gcloud run jobs deploy $SERVICE_NAME \
          --tasks 1 \
          --parallelism 1 \
          --max-retries 3 \
          --task-timeout 1m \
          --image $IMAGE \
          --project $GCP_PROJECT_ID \
          --region $GCP_REGION \
          --service-account $SERVICE_ACCOUNT_NAME \
          --set-secrets=ID=ID:latest,CLIENT_SECRET=CLIENT_SECRET:latest

詳細(読み飛ばしても可)

Checkout repository

コードを読み込むやつ

- name: Checkout repository
  uses: actions/checkout@v4

auth

secrets.GCP_SA_KEYを使ってログインしてくれるやつ

- id: "auth"
  uses: "google-github-actions/auth@v2"
  with:
    credentials_json: "${{ secrets.GCP_SA_KEY }}"

Configure docker

Artifact Registryにdocker imageを格納していくけど、どこの領域に入れていくのかを事前に設定しておかないといけないのでここでやる。

- name: Configure docker to use the gcloud cli
  run: gcloud auth configure-docker ${{ secrets.GCP_REGION }}-docker.pkg.dev --quiet

Delete old image

Artifact Registry格納していくのはいいけど、自動で削除されたりはせず、たまり続けてしまう。
そのまま無料枠の容量も超えてしまうので、一度全部削除する。
初回実行時はそもそも削除するものがなくエラーが出るので、continue-on-errorをオンにしています。

0.5GBまでなら無料。

https://cloud.google.com/artifact-registry/pricing?hl=ja#storage

- name: Delete old image
  continue-on-error: true
  run: gcloud artifacts docker images delete ${{ env.IMAGE }} --quiet

Build and Push

そのまま。ビルドしてぶち込む。

- name: Build a docker image
  run: docker build -t ${{ env.IMAGE }} .

- name: Push the docker image
  run: docker push ${{ env.IMAGE }}

Deploy to Cloud Run

Artifact Registry格納したdocker imageを使ってcloud run jobsをデプロイする。
指定できるオプションは以下に記載がある。

https://cloud.google.com/sdk/gcloud/reference/run/jobs/create

 - name: Deploy to Cloud Run
   run: | 
     gcloud run jobs deploy $SERVICE_NAME \
       --tasks 1 \
       --parallelism 1 \
       --max-retries 3 \
       --task-timeout 1m \
       --image $IMAGE \
       --project $GCP_PROJECT_ID \
       --region $GCP_REGION \
       --service-account $SERVICE_ACCOUNT_NAME \
       --set-secrets=ID=ID:latest,CLIENT_SECRET=CLIENT_SECRET:latest

最後の--set-secretsはSecret Managerで設定している変数を持ってこれる。

--set-secrets=[ReferencedValue]=[SecretValue]:[varsion]
変数 内容
[ReferencedValue] プログラム中で参照できる変数(process.env.[ReferencedValue])
[SecretValue] Secret Managerに設定されている変数名
[varsion] 使用する変数のバージョン

github側に設定するSecretとか

設定するのは以下の変数です。githubのSecrets and variables→Actions→Secretsに登録していきましょう。GCP_SA_KEYの作り方とかは次の章で記載。

変数 内容
GCP_PROJECT_ID プロジェクトのID
GCP_REGION デプロイするリージョン(東京だとasia-northeast1)
GCP_SA_KEY デプロイする際にGithub Actionsが利用する権限のAPIキー(json)
SERVICE_ACCOUNT_NAME cloud run jobsが実行される際にこの権限を持って実行される
SERVICE_NAME これがジョブの名前とかになるのでいい感じの名前にする

こんな感じ。

GCPの権限設定

GCPで必要なアカウントは大きく以下2つ

  • github actionsがGCPにデプロイするときに利用するアカウント
  • cloud runが実行される際に利用するアカウント

github actionsのアカウント

以下のロールを割り当てています。
cloud runの権限はもう少し絞れるのかも。
Artifact Registryは書き込みだけでなく削除も実施するので管理者にしています。

アカウントとAPIキーの作成手順

  1. IAMと管理→サービスアカウント→サービスアカウントを作成
  2. いい感じの名前を付けて作成して続行
  3. 先ほどの3つの権限をつけて続行
  4. ③は無視して完了
  5. アカウントが作成されているので選択してキー→鍵を追加→新しいかぎを作成
  6. JSONを選択して作成
  7. JSONファイルがDLされるので、それをコピーしてgithub側のSecrets(GCP_SA_KEY)に登録する

cloud runのアカウント

Secret Managerに設定している変数を利用するので、その権限が必要になります。
firestoreとか別のところにアクセスする必要があると、その権限も必要になるかも。ここはやりたいことによって異なると思うので、適宜追加してください。

アカウントの作成手順はgithub actionsと一緒でアカウントのアドレスをコピーしてgithub側のSecrets(SERVICE_ACCOUNT_NAME)に登録する

Artifact Registryのリポジトリーを作成する

docker pushではリポジトリーを自動で作成してくれません。そのままmasterブランチにpushしてしまうと、権限がないか、リポジトリーがないよというエラーが出ます。

denied: Permission "artifactregistry.repositories.uploadArtifacts" denied on resource "projects/***/locations/***/repositories/***" (or it may not exist)
Error: Process completed with exit code 1.

Artifact Registry→リポジトリー→リポジトリーを作成から作成できるので事前に作成しておきましょう。
名前はSERVICE_NAME、リージョンはGCP_REGIONでgithubに格納した値と一緒にしましょう。

まとめ

一旦デプロイまでいけたのでメモとして残しました。なにか不備があれば指摘お願いします!
Container Registryが非推奨になっていたので、Artifact Registryを使うようにしたのですが、細かい部分が変わっていてそこがつまづきポイントでした。
実際に利用しているわけではないので、気づいたことがあれば追記していきます。

Discussion