Google Cloud で機密情報を保管するときには Secret Manager が使えます。
Secret Manager | Google Cloud
ためしに、Google Cloud Console で Secret Manager に値を保存した後、ローカル環境のPythonスクリプトで Secret Manager の値を取得しようとしてみました。
まず公式ドキュメントを読んだところ、Pythonスクリプトでの実装は「シークレットの作成と読み取り」を同時に行っていました。
Secret Manager client libraries | Secret Manager Documentation | Google Cloud
そこで、シークレットの作成を別途行う時の実装について色々調べたため、メモとして残します。
目次
環境
- WSL2上のUbuntu 22.04.1 LTS
- Python 3.10.7
- google-cloud-secret-manager 2.12.6
- Python用のSecret Managerクライアントライブラリ
Windows上での作業
Google Cloud の Secret Manager まわりの設定
今回は、Windows上のブラウザにて、 Google Cloud の Console を使って設定します。
Secret Manager でシークレットを作成
まずは、Secret Manager APIを有効化し、シークレットを作成します。
今回は test というシークレットに ham という値を設定します。
| 項目 | 値 |
|---|---|
| 名前 | test |
| シークレットの値 | ham |
| このシークレットのロケーションを手動で管理する | チェックしない |
| 顧客管理の暗号鍵(CMEK)を使用する | チェックしない |
| ローテーション期間を設定する | チェックしない |
| 有効期限を設定する | チェックしない |
サービスアカウントの作成とアクセスキーの生成
Secret Manager からシークレットを取得するため、新たに専用のサービスアカウントを作成します。
また、サービスアカウントで Secret Manager の値を読み取れるようなロールを割り当てます。
公式ドキュメントを読むと、 Secret Manager のシークレット アクセサー (roles/secretmanager.secretAccessor) を割り当てれば良さそうです。
Secret Manager のロール | ロールについて | IAM のドキュメント | Google Cloud
それでは作成していきます。
IAMのサービスアカウントから、 サービスアカウントの作成 を選択します。
| 項目 | 値 |
|---|---|
| サービスアカウント名 | python-secret-manager-test |
| サービスアカウントID | python-secret-manager-test |
| ロール | Secret Manger のシークレットアクセサー |
続いて、サービスアカウントのアクセスキーを生成します。
キー タブから 鍵を追加 > 新しい鍵を作成 を選択し、キーのタイプを JSON として作成し、Windows上に JSON ファイルをダウンロードします。
WSL2上のUbuntuでの作業
Python環境を構築
WSL2上の適当なディレクトリにて、Python環境を作成します。
# 仮想環境を有効化 $ python -m venv env $ source env/bin/activate # PythonのSecret Managerクライアントライブラリをインストール (env) $ pip install google-cloud-secret-manager
Pythonスクリプトを作成
今回は、Secret Managerクライアントライブラリの3つのメソッドを使って、シークレットの値を取得します。
from_service_account_json()- ダウンロードしたJSONファイルから、Secret Managerクライアントを生成するメソッド
- from_service_account_json | Class SecretManagerServiceClient (2.12.6) | Python client library | Google Cloud
- 今回は環境変数
GOOGLE_APPLICATION_CREDENTIALSを設定しないので、このメソッドを使って認証情報を所持済のクライアントを生成
- 今回は環境変数
secret_version_path()- Secret Managerからシークレットの値を取得する時に使う
nameを取得するメソッド - secret_version_path | Class SecretManagerServiceClient (2.12.6) | Python client library | Google Cloud
nameのフォーマットは今のところ固定なため、f-stringsなどで定義しても良さそうではある
- Secret Managerからシークレットの値を取得する時に使う
access_secret_version()- Secret Managerからシークレットの値を取得するメソッド。似たようなメソッドに
get_secretやget_secret_versionはあるが、これらはメタデータを取得するメソッド - access_secret_version | Class SecretManagerServiceClient (2.12.6) | Python client library | Google Cloud
- Secret Managerからシークレットの値を取得するメソッド。似たようなメソッドに
スクリプトの全体はこんな感じです。
先頭の4つの定数は、適宜環境に合わせます。
from google.cloud import secretmanager PROJECT_ID = 'your_project_id' SECRET_ID = 'test' # Secret Manager で設定したシークレットID VERSION = 'latest' CREDENTIAL_FILE_NAME = 'your_json_file.json' def main(): # clientを生成 client = secretmanager.SecretManagerServiceClient.from_service_account_json(CREDENTIAL_FILE_NAME) # path を取得 path = client.secret_version_path(PROJECT_ID, SECRET_ID, VERSION) # Secret Manager からシークレットを取得 response = client.access_secret_version(name=path) # シークレットをデコード value = response.payload.data.decode('UTF-8') # 表示 print(value) if __name__ == "__main__": main()
JSONファイルをWSL2上にコピー
Windowsでダウンロードしたサービスアカウント用のJSONファイルを、WSL2上にコピーします。
WSL2上のコピー先は、上記で作成したPythonスクリプトと同じディレクトリにします。
Pythonスクリプトの実行
実行すると、Secret Managerに保存したシークレットの値 ham が取得できました。
$ python run.py ham
その他
Cloud SDKの公式ドキュメントの場所について
最近場所が変更されたようです。
Productivity unlocked with new Cloud SDK reference docs | Google Cloud Blog