gcloud CLI にカレントプロジェクトをなるべく持たせないようにして暮らしている。
gcloud はデフォルトでカレントプロジェクトのリソースを操作する。操作するプロジェクトが 1 つなら良いけど、仕事でも遊びでもいくつもの GCP プロジェクトを扱っているので、うっかり異なるプロジェクトのリソースを操作してしまったり、意図しないプロジェクトに費用が計上されてしまうのが嫌だから。
カレントプロジェクトは設定しないようにして、gcloud を使う時は都度 --project=PROJECT_ID
で渡すようにしている。
# カレントプロジェクトを確認するには以下のコマンドなど $ gcloud config get-value project $ gcloud config list # カレントプロジェクトの設定を消す $ gcloud config unset project
ローカルの ADC の quota project
忘れられがちだけど、ローカルの Application Default Credentials にもカレントプロジェクトに相当する "quota project" がある。
ADC についてはこちら
blog.pokutuna.com
ADC の quota project は、gcloud auth application-default login
した時点のカレントプロジェクトが設定される。
~/.config/gcloud/application_default_credentials.json
を見ると分かるし、ログイン時のメッセージにも出てくる。
Credentials saved to file: [/Users/pokutuna/.config/gcloud/application_default_credentials.json] These credentials will be used by any library that requests Application Default Credentials (ADC). Quota project "pokutuna-playground" was added to ADC which can be used by Google client libraries for billing and quota. Note that some services may still bill the project owning the resource.
普段からカレントプロジェクトを設定しないようにしていると気にしなくて良いが、unset したり切り替えたりしていると gcloud のカレントプロジェクトと ADC の quota project が異なる状態になるのがややこしい。
なのでこれも設定しないようにしている。
カレントプロジェクトを ADC に伝播させたくない場合は ADC ログイン時に --disable-quota-project
オプションを使う。
$ gcloud auth application-default login --disable-quota-project
ADC に quota project を設定しない場合、以下のような警告を見ることになるけど、アプリケーションコードからプロジェクト ID を与えればよいので気にしない。
WARNING: Cannot find a quota project to add to ADC. You might receive a "quota exceeded" or "API not enabled" error. Run $ gcloud auth application-default set-quota-project to add a quota project.
ADC にプロジェクト ID を持たせない暮らし
ADC に quota project を設定しない場合、アプリケーションコード中にプロジェクトIDが登場することになるけど、意図しないプロジェクトを操作してしまう危険を避けることを優先している。
認証情報はメンドイので ADC に解決してほしいが、プロジェクト ID まで暗黙に解決したいことはほぼないし、複数のプロジェクトで同じコードを実行する場合でも、設定や環境変数などでアプリケーションに伝えればいいという考え。
GCP 上の実行環境でも、実行環境とプロジェクト ID が異なってないなら問題はない。
Node
Google Cloud の各種プロダクトに用意されたクライアントライブラリはコンストラクタに渡せばいい。
// Imports the Google Cloud client library const {BigQuery} = require('@google-cloud/bigquery'); const client = new BigQuery({ projectId: "<PROJECT_ID>" });
Spreadsheet など、Google Cloud 感ないものは GoogleAuth
に渡す。Spreadsheet や Calendar なども API を有効にしたり使用量を管理するために Google Cloud プロジェクトが必要。
googleapis/google-api-nodejs-client
import { google } from "googleapis"; const auth = new google.auth.GoogleAuth({ projectId: "<PROJECT_ID>", scopes: [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/spreadsheets.readonly", ], }); const sheets = google.sheets({ version: "v4", auth });
Node の場合、明に指定しない場合は google-auth-library がプロジェクト ID を解決しようとする。その過程で GCLOUD_PROJECT
や GOOGLE_CLOUD_PROJECT
環境変数を参照したり、gcloud
のカレントプロジェクトを参照したりする(歴史的経緯だろうけど、この挙動が嫌だなあ)。
Go
Go でも Google Cloud 系のクライアントライブラリでは素直に渡せばいい。
import ( "context" "cloud.google.com/go/bigquery" ) func main() { ctx := context.Background() client, err := bigquery.NewClient(ctx, "<PROJECT_ID>") ... }
Google Cloud 感のないものは google.golang.org/api
を使うことになるが、こちらは option.WithQuotaProject()
を使う。google.golang.org/api
以下でほぼすべての Google の API を叩けるので、Cloud API もこちらの方法で叩ける。
googleapis/google-api-go-client
import ( "context" "google.golang.org/api/option" "google.golang.org/api/sheets/v4" ) func main() { ctx := context.Background() client, err := sheets.NewService(ctx, option.WithQuotaProject("<PROJECT_ID>")) ... }
まとめ
- いろんなプロジェクトを触る場合は gcloud にカレントプロジェクトを設定しないのをおすすめしている
- ローカルの ADC も quota project があり、ログイン時のカレントプロジェクトが引き継がれる、これも設定しないのがいい
- アプリケーションコードでプロジェクト ID を明に指定すればいい