Closed8
Cloud Build のサービスアカウントを明示的なものに付け替える
4月29日以降に新しく作成するプロジェクト以外は対象外のようだが、せっかくなので既存のプロジェクトでもサービスアカウントを明示的なものにしておく。
方針
- Cloud Build のデフォルトサービスアカウントに設定されているロールを抽出する
- Terrafrom で新しいサービスアカウントをつくり、必要なロールを設定し、ビルドトリガーに指定する
ロールの抽出
gcloud projects get-iam-policy <project-name> \
--flatten="bindings[].members" --format='table(bindings.role)' \
--filter="bindings.members:wada.yusuke@classmethod.jp"
ぜんぜんわかりませんでした。ありがとう Stack Overflow。
で、これを 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
...
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}"
}
`)
})
ビルドをトリガーできませんでした: 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
ログの保存方法を指定する必要がある。
これは 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
``'
ビルドエラー: 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}",
]
}
ここまでやってビルドが成功した
- サービスアカウントを作成して権限を付与する
- Artifat Registryでこのサービスアカウントのアクセスを許可する
- トリガーにサービスアカウントを指定する
- cloudbuild.yml でロギングオプションを明示する
このスクラップは2024/03/11にクローズされました