GAミント至上主義

Web Monomaniacal Developer.

CircleCIからCloud Runにデプロイするときにハマった3つのエラー

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だけでフィルタし、ページ送りしまくったらやっとみつかったので、カスタムロールを作成。 f:id:uyamazak:20220107111632p:plain

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: プロジェクトの番号