GCPのCloud Functionsでサービスアカウントで起動したにも関わらず、テスト実行が上手くいかなかったので解決方法をメモ
状況
1., Cloud Functionsでサービスアカウントを指定
2., Pythonで以下のコマンドをテスト実行
from google.auth import default
import gspread
creds, _ = default()
gc = gspread.authorize(creds)
3., 権限を設定したにも関わらず、以下のエラーが出力
gspread.exceptions.APIError: APIError: [403]: Your application is authenticating by using local Application Default Credentials. The sheets.googleapis.com API requires a quota project, which is not set by default. To learn how to set your quota project, see https://cloud.google.com/docs/authentication/adc-troubleshooting/user-creds .
原因
Cloud Functionsでテスト実行を行うと、Cloud Shellが立ち上がるが、これはサービスアカウントに紐づかず、デフォルトのアカウントで立ち上がる。そのため、default()によるクレデンシャル認証の場合、デフォルトアカウントで認証される。
解決方法
公式では3パタンの運用を紹介している。
https://cloud.google.com/docs/authentication/application-default-credentials
1., GOOGLE_APPLICATION_CREDENTIALS 環境変数
2., Google Cloud CLI で設定されたユーザー認証情報
3., 接続済みのサービス アカウント(メタデータ サーバーから返されます)
1と2については、サービスアカウントのキー情報やパス情報を変数に埋め込む、もしくは認証を事前に行う方法である。今回は、キー情報は管理したくない(GCPで運用することでお任せしたい)モチベーションであったため、テスト環境での実行を諦め、workflowsでテスト実行を行うことにした。
同一プロジェクト内のworkflowsであればOIDC認証を利用できるので以下で実行。
workflows
==略==
- sample_cloud_func:
call: http.get
args:
url: ${function_url}
auth:
type: OIDC
まとめ
Cloud Funcitonsで指定するサービスアカウントを指定してもテスト環境のメタ情報はデフォルトアカウントなので注意。
コメント