Cloud Buildのトリガー作成時にサービスアカウントを指定してみた
データアナリティクス事業本部の根本です。Cloud Buildのトリガー作成時にサービスアカウントを指定して作成するという検証をしてみました。
デフォルトのサービスアカウントではなく明示的にサービスアカウントを指定してトリガー作成をしたい、という方がいれば読んでみていただけると嬉しいです。
この記事の対象者
- Cloud Buildでサービスアカウントを指定してトリガーを作成したいひと
前提条件
- Cloud Buildでデフォルトサービスアカウントで作成したトリガーがあること
- Cloud BuildとGitHubが連携していること、デプロイできるCloud Functions関数があること
検証の目的
- Cloud Buildでサービスアカウントを指定してトリガー作成できるか。つまづきポイントがないか
- サービスアカウントを指定したトリガーでCloud Functionsの関数がデプロイできるか
上記ができるかどうかを検証していきます。
前準備:サービスアカウント作成
サービスアカウントをgcloudコマンドにて作成します。
gcloud iam service-accounts create test-cloudbuild-sa \ --description="test" \ --display-name="test-cloudbuild-sa"
作成したサービスアカウントに対して、以下の権限を付与します。
- iam.serviceAccountUser
- cloudfunctions.developer
iam.serviceAccountUser
ロールをサービスアカウントに付与することで、サービスアカウントがCloud Functionsなど他のリソースにアクセスしたり、作成削除などの操作を行うことができるようになります。
ただし、Cloud Functionsへの操作権限は何もないロールなので別途権限付与が必要です。
Cloud Functions関数作成のため、cloudfunctions.developer
ロールを併せて付与することで、この権限をサービスアカウントが使用することができます。
gcloud projects add-iam-policy-binding *project-id* \ --member serviceAccount:test-cloudbuild-sa@*project-id*.iam.gserviceaccount.com \ --role roles/cloudfunctions.developer gcloud projects add-iam-policy-binding *project-id* \ --member serviceAccount:test-cloudbuild-sa@*project-id*.iam.gserviceaccount.com \ --role roles/iam.serviceAccountUser
前準備:ビルド構成ファイル
リポジトリには以下のビルド構成ファイル(cloudbuil.yaml)を準備しました。
steps: - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: 'bash' args: - '-c' - | gcloud functions deploy test_function \ --gen2 \ --region=asia-northeast1 \ --runtime=python311 \ --source=./test_function \ --entry-point=get_file_names \ --trigger-http
前準備:トリガー作成
トリガーを作成します。
gcloud builds triggers create github \ --name="test-nemoto-trigger" \ --region='asia-northeast1' \ --repo-owner='リポジトリ所有者' \ --repo-name='リポジトリ名' \ --build-config='cloudbuild.yaml' \ --service-account="projects/*project-id*/serviceAccounts/test-cloudbuild-sa@*project-id*.iam.gserviceaccount.com" \ --branch-pattern="main"
service-account
で、作成したサービスアカウントを指定しています。*project-id*
やサービスアカウント名は適切なものに置き換えてください。
検証:トリガーを動作させてみる
リポジトリにpushされたら動作するトリガーで作成していますが、Cloud Buildの画面上で手動起動して動作を確認してみます。
Cloud Buildのサービス画面>トリガー一覧にて、該当トリガーの右側実行
ボタンを押下します。
実行ボタンを押下したところ、トリガーの実行に失敗しました。
エラーメッセージを見てみます。
ビルドをトリガーできませんでした: 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
サービスアカウントを指定した場合、ログに関しての追加設定が必要となるようです。
具体的には、ログを保存するバケットを明示的に指定するか、CLOUD_LOGGING_ONLY
(バケットには保存しないでCloud Loggingにだけ保存する)またはNONE
(ログを保存しない)のログオプションを使用する
必要があります。デフォルトのサービスアカウントを使用する場合(サービスアカウントの指定なし)でログに関する設定を指定しなかった場合、CLOUD_LOGGING_ONLY
が設定されます。
バケットへの保存は不要でCloud Loggingへの保存だけで良い場合はCLOUD_LOGGING_ONLY
を設定します。今回はCloud Loggingへの保存だけで良いので、ビルド構成ファイル(cloudbuild.yaml)の最下行に以下を実装しました。
options: logging: 'CLOUD_LOGGING_ONLY'
上記を追加して再度手動でトリガーを実行してみます。
トリガーの実行に成功しました!が、ビルドに失敗しました。
気になるエラーメッセージが出ていたので見てみます。
The service account running this build does not have permission to write logs. To fix this, grant the Logs Writer (roles/logging.logWriter) role to the service account.
ログ出力に関して権限が足りないようです。ビルドのログも何も出力されていません。
それでは、ログを出力するための権限roles/logging.logWriter
を以下のコマンドで付与してみます。
gcloud projects add-iam-policy-binding *project-id* \ --member serviceAccount:test-cloudbuild-sa@*project-id*.iam.gserviceaccount.com \ --role roles/logging.logWriter
権限の付与ができたら再度トリガーを手動実行してみます。
ビルドが成功していました!ログもちゃんと出力されています。
それではCloud Functions関数が作成されているかも確認します。
ビルド構成ファイル(cloudbuild.yaml)に指定した関数が無事作成されていました。無事にデプロイまでできてよかったです。
まとめ
サービスアカウントを指定してのトリガー作成をしてみて、デフォルトのサービスアカウントであれば気にしていなかったログ設定ですが、指定した場合にはCLOUD_LOGGING_ONLY
やバケット指定が必要になるという点を知れたのはよかったです。
既存設定でバケットやログ出力設定を指定してのトリガー作成をしていた場合は問題ないですが、特に指定してなかった場合でサービスアカウントを指定した場合は引っ掛かりポイントになるかも知れません。
この記事が誰かの役に立てば幸いです。それではまた。
参考
Cloud Functions IAM
【アップデート】Cloud Build デフォルト サービス アカウントの変更と新しい組織ポリシー