Overview
CloudRun で開発したアプリケーションを GitHub Actions 経由で CloudRun にデプロイします。
202307時点の公式のドキュメントの記載だと不十分な部分があったので、現時点でのGitHub Actions 経由でのデプロイ方法を記載します。
準備
以下の API を有効化しておいてください。
- IAM Service Account
- Cloud Build
- Artifact Registry
Cloud Run のデプロイ方法
GitHub Actions を経由する前に Cloud Run にはいくつかのデプロイ方法があります。これは以下の公式ドキュメントに記載してあります。
Cloud Run にアプリケーションをデプロイする方法は以下の3つがあり、どれを採用しても大丈夫です。
今回自分は 3 のソースコードからデプロイする前提で進めます。理由は最新の main ブランチの状態をデプロイするフローにするには、main にマージ時点での最新版のソースコードをベースにしてデプロイするのが、シンプルかなと考えたからです。
1 のDocker Image は毎回作成して Push するのがめんどくさかったので、すべての処理を Cloud Build に任せて乗っかる、という方法を採用した、という流れです。
環境変数を追加する
実行環境で環境変数を追加する場合は公式ドキュメントでいくつか紹介されてます。 ref: 環境変数を構成する | Google Cloud Functions に関するドキュメント
簡単に利用できるのは以下かなと思います。
環境変数の中身にいくつかクレデンシャルの情報を入れますが、それらを GitHub のコミットに追加したくなかったので 1 or 3 で、今回は 3 を採用して、GitHub Actions の実行時に .env.yaml
を作成していく方法を採用しました。
権限について
CloudRun に GitHub Actions (外部サービス)経由でデプロイするには専用のサービスアカウントが必要になります。
このサービスアカウントにどの権限を付与するのか、がドキュメントに書いてないことが原因で色々ハマったので、その権限について書いている、というのがこのエントリの内容になるのですが、 結論から先に書いてしまうとデプロイ用のサービスアカウントに対して以下の権限を追加することで GitHub Actions からデプロイできるようになります。
roles/run.admin
roles/iam.serviceAccountUser
roles/cloudbuild.builds.builder
roles/artifactregistry.reader
これは最後に載せている参照先の中の 【Cloud Run】 デプロイするために必要なパーミッション(GCP) - Qiita に書いてある内容そのままでした。
権限付与手順
サービスアカウントの作成と借用権限の設定
$ gcloud iam service-accounts create $ServiceAccount $ gcloud iam workload-identity-pools create $PoolName --location="global"` $ gcloud iam workload-identity-pools providers create-oidc $ProviderName \ --location="global" \ --workload-identity-pool=$PoolName \ --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.actor=assertion.actor,attribute.aud=assertion.aud" \ --issuer-uri="https://token.actions.githubusercontent.com" # 権限の借用 $ PoolID=$( gcloud iam workload-identity-pools describe $PoolName \ --location="global" \ --format="value(name)" \ --project=$ProjectName ) $ gcloud iam service-accounts add-iam-policy-binding "${ServiceAccount}@${ProjectName}.iam.gserviceaccount.com" \ --role="roles/iam.workloadIdentityUser" \ --member="principalSet://iam.googleapis.com/${PoolID}/attribute.repository/${GitHubRepo}"
権限の追加
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/run.admin"
※ 上記の role をそれぞれ追加する。
GitHub Actions の設定ファイル
source からデプロイする場合
jobs: deploy: strategy: matrix: os: [ubuntu-latest] runs-on: ${{ matrix.os }} permissions: contents: "read" id-token: "write" steps: - name: Checkout uses: actions/checkout@v3 - id: "auth" name: "Authenticate to Google Cloud" uses: "google-github-actions/auth@v1" with: workload_identity_provider: ${{ secrets.WORKLOAD_IDENTITY_PROVIDER }} service_account: ${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}@${{ secrets.GCP_PROJECT_ID }}.iam.gserviceaccount.com - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v1 - name: Deploy to Cloud Run run: |- echo "GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}" > .env.yaml echo "LINE_MESSAGE_CHANNEL_SECRET: ${{ secrets.LINE_MESSAGE_CHANNEL_SECRET }}" >> .env.yaml echo "LINE_PUBLIC_KEY_ID: ${{ secrets.LINE_PUBLIC_KEY_ID }}" >> .env.yaml echo "LINE_CHANNEL_ID: '${{ secrets.LINE_CHANNEL_ID }}'" >> .env.yaml echo "LINE_PRIVATE_KEY: ${{ secrets.LINE_PRIVATE_KEY }}" >> .env.yaml echo "LINE_CHANNEL_ACCESS_TOKEN: ${{ secrets.LINE_CHANNEL_ACCESS_TOKEN }}" >> .env.yaml gcloud run deploy $SERVICE_NAME \ --project=$GCP_PROJECT_ID \ --region=$REGION \ --service-account=$GCP_DEPLOY_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com \ --allow-unauthenticated \ --cpu=2 \ --memory=512Mi \ --timeout=60 \ --platform managed \ --env-vars-file ./.env.yaml \ --source ./$SourceRepo
Docker Image からデプロイする場合
jobs: deploy: strategy: matrix: os: [ubuntu-latest] runs-on: ${{ matrix.os }} defaults: run: working-directory: ./$SourceRepoName permissions: contents: "read" id-token: "write" steps: - name: Checkout uses: actions/checkout@v3 - id: "auth" name: "Authenticate to Google Cloud" uses: "google-github-actions/auth@v1" with: workload_identity_provider: ${{ secrets.WORKLOAD_IDENTITY_PROVIDER }} service_account: ${{ secrets.GCP_DEPLOY_SERVICE_ACCOUNT }}@${{ secrets.GCP_PROJECT_ID }}.iam.gserviceaccount.com - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v1 - name: Authorize Docker push run: gcloud auth configure-docker - name: Build Images run: | echo $EnvNameKey=$EnvNameVal > .env docker build -t asia.gcr.io/${{ secrets.GCP_PROJECT_ID }}/$ImageName:$TagName --platform linux/amd64 . - name: Push Images run: docker push asia.gcr.io/${{ secrets.GCP_PROJECT_ID }}/$ImageName:$TagName - name: Deploy to Cloud Run run: | gcloud run deploy $SERVICE_NAME \ --project=$GCP_PROJECT_ID \ --region=$REGION \ --service-account=$GCP_DEPLOY_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com \ --image asia.gcr.io/${{ secrets.GCP_PROJECT_ID }}/$ImageName:$TagName \ --allow-unauthenticated \ --cpu=2 \ --memory=512Mi \ --timeout=60 \ --platform managed
See Also
以下のエントリをいくつか参考にさせてもらいました。