本日も乙

ただの自己満足な備忘録。

Cloud Asset APIでGCPプロジェクト、フォルダ、組織内のIAMリソースを検索する

組織配下の GCP プロジェクトが増えるにつれて管理が煩雑になってきます。私の場合、異動・退職者の IAM ユーザ削除に頭を悩ませていました。私が管理しているフォルダ配下の GCP プロジェクトでは Google グループで IAM を管理していてとても楽なのですが、他部署横断型の GCP プロジェクトや開発のお手伝いといった形で他部署の GCP プロジェクトに IAM ユーザが登録されているケースもしばしばあります。

退職者が出た場合に、すべてのアカウントを削除するようにしているのですが、特定の IAM ユーザを探すのはとても至難です。GCP プロジェクトを一つずつ探していかないといけないですし、フォルダ も探さないといけないですし、経理関係に関わっている人なら請求アカウントもチェックしないといけないですし、サポートに紐付けたアカウントも見なければなりません。規模が大きくなると一つずつチェックする作業が破綻します。

最近、Cloud Asset API で IAM リソースを組織・フォルダ・プロジェクトを横断して検索する機能がリリースされました。まさに私が求めていた機能そのものです。

twitter.com

本記事では、Cloud Asset API で組織・フォルダ・プロジェクトから IAM リソースを検索する方法についてまとめました。

ドキュメント Searching Cloud IAM policies  |  Cloud Asset Inventory Documentation

Cloud Asset API の有効化

「APIとサービス」→「ライブラリ」から Cloud Asset API で検索して、Cloud Asset API を有効化します。

enable-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_IDprojects/PROJECT_NUMBER
  • フォルダの場合 folders/FOLDER_NUMBER
  • 組織の場合 organizations/ORGANIZATION_NUMBER

QUERY は検索するためのクエリです。

IAM ポリシーを検索する場合は policy : xxxx、プロジェクトを検索する場合は resource : xxx とします。

例えば、組織 1234567890123ohsawa@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'

参考文献