GKEにおけるDigdagでのGCPのクレデンシャルの取り扱い

bqオペレータとgcloudコマンドのクレデンシャルのズレ

Posted on Sunday, March 21, 2021

TOC

DigdagとGCP

Digdagはワークフローエンジンとして有名なソフトで、複数個のタスク間の依存関係からなるワークフローを定義し、そのワークフローの実行及び管理を行う。

具体的に、複数テーブルのインポートを行いたいとなったとき、それらに対して逐次的にEmbulkを手で叩くのではなく、DigdagがうまいことEmbulkを叩いてくれる。

+some_job:
  sh>: embulk run some_table.yaml.liquid

そんなDigdagであるが、バッチ処理に非常によく使われるため、GCPやAWSに対応したコマンドがDigdag側に用意されている。 これは本来ならば上記のようにsh>オペレータでシェルでコマンドを叩くが、BigQuery関係だとbq>とかbq_ddl>といったコマンドが用意されている。

+some_bq_job:
  bq>: queries/step.sql
  destination_table: other_project:other_dataset.other_table

これは実質的にsh>: bq ...コマンドの糖衣構文だけど、これは比較的便利なのでよく利用される。

GKEでのクレデンシャルのセット

Digdagの公式ドキュメントにはbq>オペレータを利用する際はDigdagのSecretsにサービスアカウントキーをセットするよう書いてある。

Digdagが動いているコンテナ内で以下のコマンドを叩けば良い。

$ digdag secret --project [YOUR_PROJECT_NAME] --set gcp.credential=@/path/to/sa_key.json

こうするとbq>オペレータを叩く際にこのサービスアカウントとして実行される。

しかし、ここでポイントとして、このクレデンシャルはコンテナ全体でサービスアカウントが有効化されているわけではない。

GKEでポッドの中に入ってクレデンシャルを叩くと、GKEを動作しているサービスアカウントが出てくる。

$ gcloud config list

サービスアカウントの有効化

bq>オペレータやbq_ddl>オペレータでは微妙にやりきれない作業などはたまにあり、その際は直接シェルでbqを叩きたいケースがある。

例えばテーブルのスキーマに説明を付与したくて、そのスキーマ情報はJSONで保存されているときなど。

こうした際はSQLにCREATE TABLE文でやる方法もあるが、それよりもbq updateでテーブル情報をアップデートする方が簡単だったりする。

この場合、意図的にDigdag内でサービスアカウントを有効化させるジョブを挟み込む必要があり、

+auth_sa:
  sh>: gcloud auth activate-service-account --key-file=/path/to/sa_key.json

+some_job:
  sh>: bq update my_dataset.my_table schema/my_table.json

というようにすればサービスアカウントで実行ができる。