Google Cloud のクライアントライブラリを使うと API を通して Google Cloud のリソースにアクセスすることができる。
そして多くの場合どのプロジェクトのリソースにアクセスするのかを指定する必要があるが、その指定方法は複数ある。
この記事では、プロジェクトを指定する方法としてどのようなものがあるのか、そしてどの指定方法が優先されるのか、について述べていく。
この記事の内容は以下の環境で動作確認している。
- npm パッケージ
- @google-cloud/storage@7.14.0
- dbt
- dbt-core@1.9.1
- dbt-bigquery@1.9.0
サンプルの準備
以下は対象のプロジェクトの Cloud Storage のバケット一覧を表示するコードで、クライアントライブラリ@google-cloud/storageを使って書いている。
// bucket.js const { Storage } = require("@google-cloud/storage"); const storage = new Storage(); async function listBuckets() { try { const [buckets] = await storage.getBuckets(); buckets.forEach((bucket) => console.log(bucket.name)); } catch (err) { console.error("Error:", err); } } listBuckets();
このコードを使って、「対象のプロジェクト」を指定する方法を示していく。
なお、「対象のプロジェクト」にアクセスするための認証情報は利用可能になっているものと見做す。
クライアントライブラリに認証情報を渡す方法は以下の記事に書いた。
各プロジェクトに以下のバケットが存在するものとして、話を進めていく。
- project-a
- bucket-a
- project-b
- bucket-b
- project-x
- bucket-x
- project-y
- bucket-y
準備が整ったので、優先順位が低い順に、プロジェクトを指定する方法を紹介していく。
プロジェクトを指定しなかった場合
まず最初に、いかなる方法でもプロジェクトを指定していなかった場合にどうなるのか、確認しておく。
$ node bucket.js
Error: Error: Unable to detect a Project Id in the current environment.
上記のようなエラーになる。
gcloud CLI の project プロパティ
gcloud CLI のprojectプロパティが存在すれば、それが使われる。
なので例えば以下のように設定すると、project-aプロジェクトにあるbucket-aが表示される。
$ gcloud config set core/project project-a
$ node bucket.js
bucket-a
gcloud CLI のプロパティについては、以下の記事に詳しく書いた。
この記事に書いたようにgcloud config setよりも環境変数が優先されるので、環境変数CLOUDSDK_CORE_PROJECTにproject-bを設定すると、bucket-bが表示されるようになる。
$ export CLOUDSDK_CORE_PROJECT=project-b
$ node bucket.js
bucket-b
CLOUDSDK_CORE_PROJECTは unset しておく。
$ unset CLOUDSDK_CORE_PROJECT
GOOGLE_APPLICATION_CREDENTIALS に設定した JSON ファイルの project_id
環境変数GOOGLE_APPLICATION_CREDENTIALSには JSON ファイルを指定するが、そのファイルのproject_idキーの値でも、対象のプロジェクトを指定できる。
GOOGLE_APPLICATION_CREDENTIALSについての説明も、以下の記事に書いている。
以下の結果になるため、projectプロパティよりもGOOGLE_APPLICATION_CREDENTIALSのproject_idが優先されることが分かる。
$ export GOOGLE_APPLICATION_CREDENTIALS=sa-key.json $ less sa-key.json| grep 'project_id' "project_id": "project-b", $ gcloud config list | grep 'project' project = project-a $ node bucket.js bucket-b
GOOGLE_CLOUD_PROJECT
環境変数GOOGLE_CLOUD_PROJECTにプロジェクトIDを設定すると、ここまで紹介した設定方法よりも優先される。
$ export GOOGLE_CLOUD_PROJECT=project-x
$ node bucket.js
bucket-x
コード内に直接書かれたプロジェクトID
コード内に直接プロジェクトIDを書けば、それが最優先される。
// bucket.js const { Storage } = require("@google-cloud/storage"); const storage = new Storage({ projectId: "project-y" }); // project-y を指定 async function listBuckets() { try { const [buckets] = await storage.getBuckets(); buckets.forEach((bucket) => console.log(bucket.name)); } catch (err) { console.error("Error:", err); } } listBuckets();
$ node bucket.js bucket-y
まとめ
整理すると、以下の優先順位で、対象のプロジェクトが決まる。
- コード内に直接書かれたプロジェクトID
GOOGLE_CLOUD_PROJECTGOOGLE_APPLICATION_CREDENTIALSに設定した JSON ファイルのproject_id- gcloud CLI の
projectプロパティ
dbt
データウェアハウスとして BigQuery を使用し OAuth 方式で認証を行った dbt においても、プロジェクトを明示しなかった場合は、この記事で説明した内容に基づいて対象のプロジェクトが決まる。
profiles.ymlを以下の内容にし、他の yml ファイル等でもプロジェクトを指定しなかった場合などが、このケースにあたる。
my_profile_1: target: dev outputs: dev: type: bigquery method: oauth dataset: dest
なお、公式ドキュメントには以下のように書かれているが、これまで述べてきたようにgcloud config setよりもCLOUDSDK_CORE_PROJECTやGOOGLE_CLOUD_PROJECTが優先されるので注意する。
If you do not specify a project/database and are using the oauth method, dbt will use the default project associated with your user, as defined by gcloud config set. https://docs.getdbt.com/docs/core/connect-data-platform/bigquery-setup