CircleCIを使っていてCloud Runが必要になったので設定したけど、いくつかハマったのでメモ
前提
この公式Orbsを使用する。
CircleCI Developer Hub - circleci/gcp-cloud-run
.circleci/config.ymlはこんな感じ。本番でなくステージング環境を作ってるので環境変数は変えてある。
version: 2.1 orbs: gcp-cloud-run: circleci/gcp-cloud-run@1.0.2 jobs: // 省略 deploy-cloud-run-staging: docker: - image: 'cimg/base:stable' steps: - checkout - gcp-cloud-run/init: gcloud-service-key: GCLOUD_SERVICE_KEY_STAGING google-project-id: GOOGLE_PROJECT_ID_STAGING - gcp-cloud-run/build: config: ./cloudbuild.yml
GCPのプロジェクトでサービスアカウントを作り、キーやプロジェクトIDなどはCircleCIの環境変数に設定済み。
今回モノレポなプロジェクトでDockerfileの場所とコンテキストの場所が異なるけど、Orbの設定ではできなさそうだったので、cloudbuild.ymlが必要になった。
シンプルにビルド、プッシュ、デプロイの3アクション。
cloudbuild.yml
steps: - id: "build the container image" name: "gcr.io/cloud-builders/docker" args: ["build", "-t", "gcr.io/${PROJECT_ID}/api-staging:${BUILD_ID}", "-f", "./Dockerfiles/api/Dockerfile", "."] - id: "push container image" name: "gcr.io/cloud-builders/docker" args: ["push", "gcr.io/${PROJECT_ID}/api-staging:${BUILD_ID}"] - id: "deploy to Cloud Run" name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: gcloud args: ['run', 'deploy', 'api-staging', '--image', 'gcr.io/${PROJECT_ID}/api-staging:${BUILD_ID}', '--region', 'asia-northeast1']
Cloud Buildは成功しているのにCircleCIでエラー
ログを表示しようとしてるのにサービスアカウントに権限がなくてエラーになってる模様。
Uploading tarball of [.] to [gs://********************_cloudbuild/source/*****************.tgz] Created [https://cloudbuild.googleapis.com/v1/projects/********************/locations/global/builds/*****************.]. Logs are available at [https://console.cloud.google.com/cloud-build/builds/*****************?project=************]. ERROR: (gcloud.builds.submit) The build is running, and logs are being written to the default logs bucket. This tool can only stream logs if you are Viewer/Owner of the project and, if applicable, allowed by your VPC-SC security policy. The default logs bucket is always outside any VPC-SC security perimeter. If you want your logs saved inside your VPC-SC perimeter, use your own bucket. See https://cloud.google.com/build/docs/securing-builds/store-manage-build-logs. Exited with code exit status 1 CircleCI received exit code 1
よく読むと答えが書いてあり
This tool can only stream logs if you are Viewer/Owner of the project
プロジェクトのオーナーか参照の権限をサービスアカウントに追加が必要。もちろん参照でいいので追加して解決。
Cloud Buildのログを出すだけなのに、プロジェクト全体が必要とはちょっと大げさな権限だなぁ。
Cloud Runにデプロイ時に権限かサービスがなくてエラー1
Step #2 - "deploy to Cloud Run": gcr.io/google.com/cloudsdktool/cloud-sdk:latest Step #2 - "deploy to Cloud Run": ERROR: (gcloud.run.deploy) PERMISSION_DENIED: Permission 'run.services.get' denied on resource 'namespaces/********************/services/api-staging' (or resource may not exist). Finished Step #2 - "deploy to Cloud Run" ERROR ERROR: build step 2 "gcr.io/google.com/cloudsdktool/cloud-sdk" failed: step exited with non-zero status: 1 BUILD FAILURE: Build step failure: build step 2 "gcr.io/google.com/cloudsdktool/cloud-sdk" failed: step exited with non-zero status: 1 ERROR: (gcloud.builds.submit) build bc02f3af-d341-4af1-98cb-0e2d396078a4 completed with status "FAILURE"
単純に最初なのでCloud Runのサービスが存在しない。
最初は手作業でサービス作って解決、と思ったらだめだった。
こちらを参考にCloud BuildのサービスアカウントにCloud RunのAdminをつけて解決するはず、と思ったらだめだった。 stackoverflow.com
Cloud Runにデプロイ時に権限かサービスがなくてエラー2
1をやったらエラーが変わった。
Step #2 - "deploy to Cloud Run": ERROR: (gcloud.run.deploy) PERMISSION_DENIED: Permission 'iam.serviceaccounts.actAs' denied on service account *****-compute@developer.gserviceaccount.com (or it may not exist).
ググると解決策が出てくるけどiam.serviceaccounts.actAs
が見つからない。
stackoverflow.com
ロール作成画面でフィルタするも出てこないのでiamだけでフィルタし、ページ送りしまくったらやっとみつかったので、カスタムロールを作成。
Cloud Buildでイメージのタグにコミットハッシュが使えなくてエラー
昔作った設定を参考に、イメージのバージョンに$COMMIT_SHAなどを使っていたけど、今回はGitレポジトリのフックではなくコマンド経由なせいか存在せず、空白になってしまいエラー。
Already have image (with digest): gcr.io/cloud-builders/docker invalid argument "gcr.io/*****api-staging:" for "-t, --tag" flag: invalid reference format See 'docker build --help'.
Substituting variable values | Cloud Build Documentation | Google Cloud
にある通り、絶対に使えるのは下記3つだけで、ビルドごとに異なるのはBuild IDだけなので必然的にそれを使うことにして解決。
$PROJECT_ID: Cloud プロジェクトの ID
$BUILD_ID: ビルドの ID
$PROJECT_NUMBER: プロジェクトの番号