本日も乙

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

他 GCP プロジェクトの GCS バケットにアクセスする

小ネタ系です。 GCS バケットがある GCP プロジェクトとは別の GCP プロジェクトから GCS オブジェクト(ファイル)を取得したい場合があったりします。AWS だとクロスアカウントを連携するために IAM ロール作って AssumeRole するとか面倒ですが、GCP だとサービスアカウントに権限を付与するだけでできます。

以下、わかりやすくするために、アクセスしたい方の GCP プロジェクトを A、GCSバケットを保有している方の GCP プロジェクトを B とします。

サービスアカウントを発行

プロジェクト A でサービスアカウントを発行します。このとき、サービスアカウント名(例 foo@bar.iam.gserviceaccount.com)を控えておいてください。

GCSバケットに対する権限を追加

GCSバケットの詳細から「権限」タブを選択し、「メンバーを追加」をクリックします。

gcs-access-policy

下図のように「新しいメンバー」にサービスアカウントを入力して、適切な権限(役割)を付けます。今回は GCS オブジェクトの参照のみなので「ストレージオブジェクト閲覧者」を選択します。

各役割の詳細はドキュメントをご参照ください。
Cloud IAM roles for Cloud Storage  |  Cloud Storage  |  Google Cloud

gcs-access-policy

下図のようにサービスアカウントが追加されていれば完了です。レガシーのところは何も設定しません。

gcs-access-policy

コマンドラインで設定する場合

次のコマンドでサービスアカウントに権限を付与することができます。

$ gsutil iam ch serviceAccount:foo@bar.iam.gserviceaccount.com:objectViewer \
    gs://<GCS_BUCKET>

確認方法

権限が付与されたか確認してみましょう。
サービスアカウントがアタッチしたGCEインスタンスで確かめてもいいですが、自分のPCで確認する場合、サービスアカウントの認証ファイル(JSON形式)で行います。認証ファイルはAWSアクセスキーと同様の扱いなので不要になったら削除しましょう。

以下のコマンドでサービスアカウントを使用してアクセス承認を得ます。

$ gcloud auth activate-service-account サービスアカウント名 \
    --key-file 認証ファイルパス \
    --project プロジェクト名

# 例
$ gcloud auth activate-service-account foo@bar.iam.gserviceaccount.com \
    --key-file ~/path/to/foo.json \
    --project test-project

権限が付与される前はエラーになります。

$ gsutil cp gs://<GCS_BUCKET>/test.txt ./
AccessDeniedException: 403 foo@bar.iam.gserviceaccount.com does not have storage.objects.list access to <GCS_BUCKET>

権限付与した後は取得できることが確認できます。

$ gsutil cp gs://<GCS_BUCKET>/test.txt ./
Copying gs://<GCS_BUCKET>/test.txt...
/ [1 files][    6.0 B/    6.0 B]
Operation completed over 1 objects/6.0 B.

まとめ

冒頭にも書きましたが、AWSのクロスアカウントより設定が簡単でいいですね。

参考