Google Cloud Storage のオブジェクトを別プロジェクトのアプリケーションからダウンロードする
複数の GCP (Google Cloud Platform) プロジェクトを運用している場合に、GCS (Google Cloud Storage) のオブジェクトを別のプロジェクトからダウンロードしたい!という場面があるかと思います。実際に試してみたので、今回はその方法をまとめます。
ここでは、アクセスされる側の GCP プロジェクトを projectA
、アクセスする側の GCP プロジェクトを projectB
と呼んで説明します。
projectB
の準備
アクセスする側 1. サービスアカウントキーを作成
GCPコンソール画面の IAMと管理>サービスアカウント
で、サービスアカウントを作成します。
作成完了したら、キー
タブで 鍵を追加>新しい鍵を作成
をクリックします。
キーのタイプは JSON を選択すると、JSONの鍵ファイルがダウンロードされます。
2. Secret Manager にサービスアカウントキーをアップロード
後ほど作成するアプリケーション内でサービスアカウントキーを使用するため、Secret Manager に登録しておきます。
Secret Manager の +シークレットを作成
をクリックし、サービスアカウントキーのJSONファイルをアップロードしてシークレットの値を登録します。
projectA
の準備
アクセスされる側
projectB
に GCS のオブジェクト閲覧権限を与える
1. projectB
に GCS バケットの閲覧権限を与えるために、バケットの権限を編集します。
プリンシパルを追加
をクリックし、projectB
のサービスアカウントを入力し、ロールは Storageオブジェクト閲覧者
を選択します。
これで、projectB
から projectA
の GCS バケットにアクセスできるようになりました。
アプリケーション作成
projectA
の GCS オブジェクトをダウンロードする Python コードを示します。オブジェクトの一覧取得やダウンロードは、GCS 公式ドキュメントのサンプルコードが参考になりました。
ポイントは以下の2点になります。
- サービスアカウントキーを使用し、
projectA
のクレデンシャルを作成する - クレデンシャルを利用して、GCSのクライアントインスタンスを作成する
Pythonサンプルコード
import os
import json
from google.cloud import storage
from google.oauth2 import service_account
# 環境変数取得
# projectAのバケット名
BUCKET_NAME = os.environ.get('BUCKET_NAME')
# projectBのサービスアカウントキー
SERVICE_ACCOUNT_KEY = os.environ.get('service_account_key')
# ダウンロードファイルの保存パス
DOWNLOAD_PATH = os.environ.get('DOWNLOAD_PATH')
def create_crendentials():
"""
サービスアカウントキーを使用してクレデンシャルを作成
Returns:
クレデンシャル
"""
credentials = service_account.Credentials \
.from_service_account_info(json.loads(SERVICE_ACCOUNT_KEY))
scoped_credentials = credentials.with_scopes(
[
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/analytics.readonly'
])
return scoped_credentials
def list_blobs(credentials, bucket_name):
"""
GCSバケットのオブジェクトを取得
Args:
credentials: クレデンシャル
bucket_name (str): GCSバケット名
Returns:
list: オブジェクト名のリスト
"""
# GCSのクライアントインスタンス作成
storage_client = storage.Client(credentials=credentials)
# 指定バケットのオブジェクト一覧を取得
blobs = storage_client.list_blobs(bucket_name)
return list(blobs)
def download_blob(credentials, bucket_name, blob_name, file_name):
"""
GCSバケットの指定オブジェクトをダウンロード
Args:
credentials: クレデンシャル
bucket_name (str): GCSバケット名
blob_name (str): オブジェクト名
file_name (str): 保存ファイル名
"""
# GCSのクライアントインスタンス作成
storage_client = storage.Client(credentials=credentials)
# 指定バケットのインスタンス取得
bucket = storage_client.bucket(bucket_name)
# 指定オブジェクトのインスタンス取得
blob = bucket.blob(blob_name)
# ダウンロードして指定パスに保存する
blob.download_to_filename(file_name)
def main(self):
"""
別のGCPプロジェクトのGCSバケットのオブジェクトを一覧表示し、ダウンロードする
"""
# クレデンシャル作成
scoped_credentials = create_crendentials()
# projectAの指定バケットのオブジェクト一覧を取得
blobs = list(list_blobs(scoped_credentials, BUCKET_NAME))
# オブジェクトのダウンロード
for blob in blobs:
file_name = DOWNLOAD_PATH + blob.name
download_blob(scoped_credentials, BUCKET_NAME, blob.name, file_name)
return "OK"
おわりに
今回は GCS バケットのオブジェクトを、別プロジェクトのアプリケーションからアクセスしてダウンロードする方法を紹介しました。アクセスされる側で権限を与えて、アクセスする側ではサービスアカウントキーを使用してクレデンシャルを作成することで、別プロジェクトからアクセスすることができました。ご参考になればうれしいです。
Discussion