小ネタ系です。 GCS バケットがある GCP プロジェクトとは別の GCP プロジェクトから GCS オブジェクト(ファイル)を取得したい場合があったりします。AWS だとクロスアカウントを連携するために IAM ロール作って AssumeRole するとか面倒ですが、GCP だとサービスアカウントに権限を付与するだけでできます。
以下、わかりやすくするために、アクセスしたい方の GCP プロジェクトを A、GCSバケットを保有している方の GCP プロジェクトを B とします。
サービスアカウントを発行
プロジェクト A でサービスアカウントを発行します。このとき、サービスアカウント名(例 foo@bar.iam.gserviceaccount.com
)を控えておいてください。
GCSバケットに対する権限を追加
GCSバケットの詳細から「権限」タブを選択し、「メンバーを追加」をクリックします。
下図のように「新しいメンバー」にサービスアカウントを入力して、適切な権限(役割)を付けます。今回は GCS オブジェクトの参照のみなので「ストレージオブジェクト閲覧者」を選択します。
各役割の詳細はドキュメントをご参照ください。
Cloud IAM roles for Cloud Storage | Cloud Storage | Google Cloud
下図のようにサービスアカウントが追加されていれば完了です。レガシーのところは何も設定しません。
コマンドラインで設定する場合
次のコマンドでサービスアカウントに権限を付与することができます。
$ 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のクロスアカウントより設定が簡単でいいですね。