組織配下の GCP プロジェクトが増えるにつれて管理が煩雑になってきます。私の場合、異動・退職者の IAM ユーザ削除に頭を悩ませていました。私が管理しているフォルダ配下の GCP プロジェクトでは Google グループで IAM を管理していてとても楽なのですが、他部署横断型の GCP プロジェクトや開発のお手伝いといった形で他部署の GCP プロジェクトに IAM ユーザが登録されているケースもしばしばあります。
退職者が出た場合に、すべてのアカウントを削除するようにしているのですが、特定の IAM ユーザを探すのはとても至難です。GCP プロジェクトを一つずつ探していかないといけないですし、フォルダ も探さないといけないですし、経理関係に関わっている人なら請求アカウントもチェックしないといけないですし、サポートに紐付けたアカウントも見なければなりません。規模が大きくなると一つずつチェックする作業が破綻します。
最近、Cloud Asset API で IAM リソースを組織・フォルダ・プロジェクトを横断して検索する機能がリリースされました。まさに私が求めていた機能そのものです。
twitter.com自分がprojectに対しどんな権限持ってるのか逆引き出来る機能が出た!!!便利これ!!!https://t.co/D4rDKXOSxS#gcp
— yu yamada (@nii_yan) 2020年3月2日
本記事では、Cloud Asset API で組織・フォルダ・プロジェクトから IAM リソースを検索する方法についてまとめました。
ドキュメント Searching Cloud IAM policies | Cloud Asset Inventory Documentation
Cloud Asset API の有効化
「APIとサービス」→「ライブラリ」から Cloud Asset API
で検索して、Cloud Asset API を有効化します。
Cloud Asset 権限の付与
cloudasset.assets.searchAllResources
が必要です。プロジェクトもしくはフォルダ配下であれば Viewer(roles/viewer
)があれば良いです。
組織全体の場合、会社のポリシーなどに従ってもらえばと思います。さすがにオーナー権限はできないと思うので、Cloud Asset Owner
もしくは Cloud Asset Viewer
を付与してもらってください。
gcloud コマンドのバージョンアップ
gcloud コマンドのバージョンを 278.0.0 以上にする必要があります。
$ gcloud components update # バージョン指定する場合 $ gcloud components update --version 278.0.0
検索する
以下のようなコマンドで検索します。
$ gcloud beta asset search-all-iam-policies \ --scope=SCOPE \ --query=QUERY \
SCOPE
は検索対象です。
- プロジェクトの場合
projects/PROJECT_ID
かprojects/PROJECT_NUMBER
- フォルダの場合
folders/FOLDER_NUMBER
- 組織の場合
organizations/ORGANIZATION_NUMBER
QUERY
は検索するためのクエリです。
IAM ポリシーを検索する場合は policy : xxxx
、プロジェクトを検索する場合は resource : xxx
とします。
例えば、組織 1234567890123
で ohsawa@example.com
という IAM ユーザを検索してみます。
$ gcloud beta asset search-all-iam-policies \ --scope='organizations/1234567890123' \ --query='policy : "user:ohsawa@example.com"'
Cloud Assets API を有効にしていないプロジェクトがある場合は以下のようなメッセージが表示されますので Yes
としてください。
API [cloudasset.googleapis.com] not enabled on project [xxxxxxxxxxx]. Would you like to enable and retry (this will take a few minutes)? (y/N)?
このような結果が返されます。プロジェクト、フォルダ、BigQuery Dataset、請求アカウントに紐付いた情報を取得できます。
# 次のバッチ表示をするためのトークン nextPageToken: CqMBCnb356Mk.....== results: # プロジェクト - policy: bindings: - members: - serviceAccount:foo@bar.iam.gserviceaccount.com - user:baz@example.com - user:ohsawa@example.com role: roles/owner etag: MTEgdW5yZWxhdGVkIGJpbmRpbmdzIG9taXR0ZWQu project: projects/123456789012 resource: //cloudresourcemanager.googleapis.com/projects/bar # フォルダ - policy: bindings: - members: - user:baz@example.com - user:ohsawa@example.com role: roles/resourcemanager.folderAdmin - members: - user:ohsawa@example.com role: roles/resourcemanager.folderEditor etag: MSB1bnJlbGF0ZWQgYmluZGluZ3Mgb21pdHRlZC4= resource: //cloudresourcemanager.googleapis.com/folders/111111111111 # BigQuery Dataset - policy: bindings: - members: - projectOwner:foooo - serviceAccount:bigquery@system.gserviceaccount.com - user:ohsawa@example.com role: roles/bigquery.dataOwner etag: MiB1bnJlbGF0ZWQgYmluZGluZ3Mgb21pdHRlZC4= version: 1 project: projects/345678901234 resource: //bigquery.googleapis.com/projects/foooo/datasets/baaaaaa # 請求アカウント - policy: bindings: - members: - user:ohsawa@example.com role: roles/billing.user etag: MiB1bnJlbGF0ZWQgYmluZGluZ3Mgb21pdHRlZC4= resource: //cloudbilling.googleapis.com/billingAccounts/xxxxxx-xxxxxx-xxxxxx # 組織 - policy: bindings: - members: - user:ohsawa@example.com role: roles/accesscontextmanager.policyAdmin - members: - user:ohsawa@example.com role: roles/billing.admin - members: - user:ohsawa@example.com role: roles/cloudasset.owner - members: - user:ohsawa@example.com role: roles/cloudsupport.admin - members: - user:ohsawa@example.com role: roles/resourcemanager.folderAdmin - members: - user:ohsawa@example.com role: roles/resourcemanager.folderMover - members: - user:ohsawa@example.com role: roles/resourcemanager.organizationAdmin - members: - user:ohsawa@example.com role: roles/resourcemanager.projectMover etag: MyB1bnJlbGF0ZWQgYmluZGluZ3Mgb21pdHRlZC4= resource: //cloudresourcemanager.googleapis.com/organizations/1234567890123
所属しているプロジェクト一覧を取得するには --format json
で JSON 形式にして jq コマンドであれこれすると良いです。
$ gcloud beta asset search-all-iam-policies \ --scope='organizations/1234567890123' \ --query='policy : "user:ohsawa@example.com"' \ --format json \ | jq -r '.results[].resource' \ | sed -e 's#.*/projects/\(.*\)#\1#g' -e '/folders/d' -e '/billingAccounts/d' -e '/organizations/d'