dbt でデータウェアハウスとして BigQuery を使う際、ローカル開発においては OAuth 方式を使うことが推奨されている。
そしてその場合はgcloud auth application-default loginコマンドを実行する必要がある。
確かにこのコマンドを実行すると BigQuery との接続が上手くいきローカルで開発できるようになる。
しかしこのコマンドは、具体的には何をしているのか。gcloud auth loginとは何が違うのか。何も分かっていなかったので調べてみた。
この記事の内容は、以下の環境で動作確認している。
- npm パッケージ
- @google-cloud/storage@7.14.0
- dbt
- dbt-core@1.9.1
- dbt-bigquery@1.9.0
Application Default Credentials
gcloud auth application-default loginについて理解するためにはまず Application Default Credentials (以下 ADC)という概念について理解したほうがよい。
ADC とは、 Google Cloud のクライアントライブラリが認証情報を取得するための仕組み。
クライアントライブラリは Google Cloud の API を叩くためのツールだが、当然ながら認証情報がなければ API を叩くことはできない。
例えば以下はproject-x-123456プロジェクトにある Cloud Storage のバケット一覧を表示するコードだが、クライアントライブラリである@google-cloud/storageに認証情報を渡さなければ動作しない。
// bucket.js const { Storage } = require("@google-cloud/storage"); const storage = new Storage({ projectId: "project-x-123456" }); async function listBuckets() { try { const [buckets] = await storage.getBuckets(); buckets.forEach((bucket) => console.log(bucket.name)); } catch (err) { console.error("Error:", err); } } listBuckets();
例えば以下のようにStorageインスタンスを作る際に認証情報を渡すと動作する(この例ではkeyFilenameにサービスアカウントキーのパスを渡している)。
const storage = new Storage({ projectId: "project-x-123456", keyFilename: "project-x-sa-key.json", });
だが ADC の仕組みを利用すれば、コードのなかに認証情報に関する情報を書くことなく、クライアントライブラリに認証情報を渡すことができる。
ADC は特定の順序で認証情報を検索し、最初に見つかった認証情報をクライアントライブラリに提供する。
最後まで認証情報が見つからなかった場合は、以下のようにエラーになる。
$ node bucket.js
Error: Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
GOOGLE_APPLICATION_CREDENTIALS
ADC はまず最初に、環境変数GOOGLE_APPLICATION_CREDENTIALSに入っている値を使おうとする。
この環境変数に認証情報の JSON ファイルの場所を設定しておくことで、そのファイルの内容がクライアントライブラリに渡される。
「認証情報の JSON ファイル」として使えるものはいくつかあるが、今回はサービスアカウントキーを使う。
$ export GOOGLE_APPLICATION_CREDENTIALS=project-x-sa-key.json
この状態でbucket.jsを実行するとproject-x-123456にあるバケットbucket-aが表示される。
$ node bucket.js bucket-a
GOOGLE_APPLICATION_CREDENTIALSを unset すると、bucket.jsは再び失敗するようになる。
$ unset GOOGLE_APPLICATION_CREDENTIALS $ echo ${GOOGLE_APPLICATION_CREDENTIALS-none} none $ node bucket.js Error: Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
~/.config/gcloud/application_default_credentials.json
GOOGLE_APPLICATION_CREDENTIALSに値が入っていなかった場合 ADC は~/.config/gcloud/application_default_credentials.jsonを使おうとする。
そして~/.config/gcloud/application_default_credentials.jsonを用意するためのコマンドが、gcloud auth application-default loginなのである。
gcloud auth application-default loginを実行するとウェブブラウザでページが開くので、その内容に沿って操作を行うと、選択したアカウントに基づき以下の形式の~/.config/gcloud/application_default_credentials.jsonが作られる。
{ "account": "", "client_id": "***.apps.googleusercontent.com", "client_secret": "***", "refresh_token": "***", "type": "authorized_user", "universe_domain": "googleapis.com" }
そうするとbucket.jsが再び成功するようになる。
$ node bucket.js bucket-a
gcloud auth application-default revokeを実行すると~/.config/gcloud/application_default_credentials.jsonは消える。
このように、gcloud auth application-default loginはあくまでも ADC 用の認証情報を用意するためのコマンドであり、gcloudコマンドやbqコマンドを実行するための認証を行うgcloud auth loginとは別のものである。
gcloud auth loginについては以下の記事で詳しく書いた。
dbt での挙動
dbt と BigQuery を接続させるために必要な認証情報も ADC を使って渡すことができる。
冒頭に貼ったドキュメントに書かれているようにgcloud auth application-default loginを使ってもよいが、ここまで書いてきたようにGOOGLE_APPLICATION_CREDENTIALSが設定されている場合はそちらが優先されるので注意する。