これはなんですか
- サービスアカウントキーを発行せずにサービスアカウント権限を使う方法を紹介します。
- ドキュメントを2週間くらい読み漁ってようやくたどり着いたのでメモしておきます。
結論
-
--impersonate-service-account=SERVICE_ACCOUNT_EMAIL
オプションを使う。
コマンドリファレンス
--impersonate-service-account=SERVICE_ACCOUNT_EMAIL
For this gcloud invocation, all API requests will be made as the given service account instead of the currently selected account. This is done without needing to create, download, and activate a key for the account. In order to perform operations as the service account, your currently selected account must have an IAM role that includes the iam.serviceAccounts.getAccessToken permission for the service account. The roles/iam.serviceAccountTokenCreator role has this permission or you may create a custom role. Overrides the default auth/impersonate_service_account property value for this command invocation.
やってみる
サービスアカウントを作成する
コンソールで作成した。gcloudで使いたい命令に合わせて適当な役割を付与する。
サービスアカウントを利用したいユーザーにサービスアカウントトークン作成者 ( roles/iam.serviceAccountTokenCreator
) 役割を付与する
コンソールで設定した。ポリシー設定はこんな感じ。
$ gcloud iam service-accounts get-iam-policy compute-engine-user@project-id-xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com
bindings:
- members:
- user:username@domain.com
role: roles/iam.serviceAccountTokenCreator
etag: BwWZ8ZWaXPY=
version: 1
サービスアカウントを利用したいユーザーにService Usage ユーザー ( roles/serviceusage.serviceUsageConsumer
) 役割を付与する
※本来は不要。APIの有効化の際に利用するので横着して付与したのを必須と勘違いしていた。。。
コンソールで設定した。Cloud IAMポリシーはこんな感じ。
$ gcloud projects get-iam-policy project-id-xxxxxxxxxxxxxxxxxxxxx
bindings:
- members:
- serviceAccount:compute-engine-user@project-id-xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com
- user:ownername@gmail.com
role: roles/owner
- members:
- user:username@domain.com
role: roles/serviceusage.serviceUsageConsumer
etag: BwWZ8b2sW30=
version: 1
gcloud コマンドのオプションに --impersonate-service-account=SERVICE_ACCOUNT_EMAIL
を指定する。
SERVICE_ACCOUNT_EMAIL
は作成したサービスアカウントのEMailアドレスである。
色々聞かれるので y
を選択してAPIを有効化する
$ gcloud projects get-iam-policy project-id-xxxxxxxxxxxxxxxxxxxxx --impersonate-service-account=compute-engine-user@project-id-xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com
WARNING: This command is using service account impersonation. All API calls will be executed as [compute-engine-user@project-id-xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com].
API [cloudresourcemanager.googleapis.com] not enabled on project
[86128378245]. Would you like to enable and retry (this will take a
few minutes)? (y/N)? y
Enabling service [cloudresourcemanager.googleapis.com] on project [86128378245]...
WARNING: This command is using service account impersonation. All API calls will be executed as [compute-engine-user@project-id-xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com].
WARNING: This command is using service account impersonation. All API calls will be executed as [compute-engine-user@project-id-xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com].
Operation "operations/acf.ce0886e2-bcb4-45dd-9773-5a276fd570e4" finished successfully.
bindings:
- members:
- serviceAccount:compute-engine-user@project-id-xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com
- user:ownername@gmail.com
role: roles/owner
- members:
- user:username@domain.com
role: roles/serviceusage.serviceUsageConsumer
etag: BwWZ8b2sW30=
version: 1
ただ、そもそも権限が通ってない場合は以下のエラーになる。 (serviceusage.services.use権限がないって言われている + APIが無効)
$ gcloud projects get-iam-policy project-id-xxxxxxxxxxxxxxxxxxxxx --impersonate-service-account=compute-engine-user@project-id-xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com
WARNING: This command is using service account impersonation. All API calls will be executed as [compute-engine-user@project-id-xxxxxxxxxxxxxxxxxxxxx.iam.gserviceaccount.com].
ERROR: (gcloud.projects.get-iam-policy) PERMISSION_DENIED: Caller does not have required permission to use project project-id-xxxxxxxxxxxxxxxxxxxxx. Grant the caller the Owner or Editor role,
or a custom role with the serviceusage.services.use permission, by visiting https://console.developers.google.com/iam-admin/iam/project?project=project-id-xxxxxxxxxxxxxxxxxxxxx and then retry
(propagation of new permission may take a few minutes).
- '@type': type.googleapis.com/google.rpc.Help
links:
- description: Google developers console
url: https://console.developers.google.com
- '@type': type.googleapis.com/google.rpc.Help
links:
- description: Google developer console IAM admin
url: https://console.developers.google.com/iam-admin/iam/project?project=project-id-xxxxxxxxxxxxxxxxxxxxx
If you want to invoke the command from a project different from the target resource project, use `--billing-project` or `billing/quota_project` property.
感想
- AWSで言う所の AssumeRole 的なことができる。鍵発行なしでAPIが叩けるので嬉しい。(多分)
- rate limitとかの罠があると思うので、高頻度の実行は考慮した方が良いと思う。
- そもそもこの使い方は推奨されているのだろうか……
参考