Closed8

Cloud Build のサービスアカウントを明示的なものに付け替える

waddy_uwaddy_u

方針

  • Cloud Build のデフォルトサービスアカウントに設定されているロールを抽出する
  • Terrafrom で新しいサービスアカウントをつくり、必要なロールを設定し、ビルドトリガーに指定する
waddy_uwaddy_u

ロールの抽出

gcloud projects get-iam-policy <project-name> \
--flatten="bindings[].members" --format='table(bindings.role)' \
--filter="bindings.members:wada.yusuke@classmethod.jp"

ぜんぜんわかりませんでした。ありがとう Stack Overflow。

https://stackoverflow.com/questions/47006062/how-do-i-list-the-roles-associated-with-a-gcp-service-account

で、これを Cloud Build のでふぉるとサービスアカウントに対して実行してみます。

gcloud projects get-iam-policy <project-name> \
--flatten="bindings[].members" --format='table(bindings.role)' \
--filter="bindings.members:xxxxxxxxxxx@cloudbuild.gserviceaccount.com"

ROLE: roles/appengine.deployer
ROLE: roles/appengine.serviceAdmin
ROLE: roles/cloudbuild.builds.builder
...
waddy_uwaddy_u

Terraform でサービスアカウントを作成

必要なロールはそのまま転記するイメージ。明示的にサービスアカウントを作成する。

const roles = ["roles/appengine.deployer",
"roles/appengine.serviceAdmin",
"roles/cloudbuild.builds.builder",
"roles/cloudfunctions.developer"]

roles.forEach(role => {

    console.log(`
resource "google_project_iam_member" "cloud_build_${role.split('/')[1].replace('.','_')}" {
  project = var.project_id
  role    = "${role}"
  member  = "serviceAccount:\${google_service_account.cloud_build.email}"
}
    `)
})
waddy_uwaddy_u
ビルドをトリガーできませんでした: generic::invalid_argument: if 'build.service_account' is specified, the build must either (a) specify 'build.logs_bucket', (b) use the REGIONAL_USER_OWNED_BUCKET build.options.default_logs_bucket_behavior option, or (c) use either CLOUD_LOGGING_ONLY / NONE logging options

https://cloud.google.com/build/docs/securing-builds/store-manage-build-logs?hl=ja

ログの保存方法を指定する必要がある。

これは cloudbuild.yml 側で以下を追記することで解決した。

options:
  # Cloud Buildのビルドログ保存方法を明示する
  # デフォルトではGoogle が作成したデフォルト バケットへビルドログが保存される
  # とくに分析用途などでは使用していないため、CLOUD_LOGGING_ONLYに変更する
  # https://cloud.google.com/build/docs/securing-builds/store-manage-build-logs?hl=ja
  logging: CLOUD_LOGGING_ONLY
``'
waddy_uwaddy_u

ビルドエラー: Artifact Registry へのプッシュに失敗

Step #1 - "build": error checking push permissions -- make sure you entered the correct tag name, and that you are authenticated correctly, and try again: checking push permission for "asia-northeast1-docker.pkg.dev/xxxx:latest": creating push check transport for asia-northeast1-docker.pkg.dev failed: GET https://asia-northeast1-docker.pkg.dev/v2/token?scope=repository%3pull&service=: DENIED: Permission "artifactregistry.repositories.uploadArtifacts"  (or it may not exist)

Artifact Registry のリポジトリ側から拒否されている様子。Artifact Registry の iam binding を追加する必要がある。

# Cloud Build に設定するサービスアカウントのID
data "google_service_account" "cloud_build_test" {
  account_id = "cloud-build"
  project = var.gcp_test_project_id
}

# ビルドプロジェクトの Cloud Build と Cloud Run からのアクセスを許可する。
resource "google_artifact_registry_repository_iam_binding" "binding_zenn_app_and_builder" {
  provider   = google-beta
  project    = var.gcp_project_id
  location   = var.artifact_registry_location
  repository = google_artifact_registry_repository.zenn.name
  role       = "roles/artifactregistry.repoAdmin"
  members = [
    "serviceAccount:${data.google_service_account.cloud_build_.email}",
  ]
}

waddy_uwaddy_u

ここまでやってビルドが成功した

  • サービスアカウントを作成して権限を付与する
  • Artifat Registryでこのサービスアカウントのアクセスを許可する
  • トリガーにサービスアカウントを指定する
  • cloudbuild.yml でロギングオプションを明示する
このスクラップは2ヶ月前にクローズされました