🕌

embulk-output-snowflake を使ってたら突然 Terraform が動かなくなった話

に公開

こんにちは!スターフェスティバル株式会社でソフトウェアエンジニアをしている吉田あひるです!
弊社では Snowflake を活用したデータ基盤の運用・構築をしており、 Snowflake 内のリソース管理には Terraform を活用しています。

なのですが、ある日突然 terraform plan を実行するとステージが見つからないというエラーが大量発生するようになり、動かなくなってしまいました。

Stage:
"HOGE_DB"."FUGA_SCEMA"."PIYO_STAGE",
Err: object does not exist

Error: Failed to show stage by id

この記事では、その原因と解決方法について共有します。

最初に結論

embulk-output-snowflake を使う時は delete_stage オプションを有効にしよう。

問題の調査

Snowflake Terraform Provider をデバッグしつつ動かしてみたところ、以下のような SQL を発行しリソースの状態を取得していることがわかりました

SHOW STAGES LIKE 'PIYO_STAGE' IN SCHEMA "HOGE_DB"."FUGA_SCHEMA";

権限周りで何か変更があったのかと思い SYSADMIN など強権限を使って Worksheet から同様の SQL を実行してみたところ、確かにクエリの結果は空のようです。

INFORMATION_SCHEMA に対してクエリを投げてみると存在が確認できたので、どうやら stage 自体は存在しているようでした。

SELECT *
  FROM INFORMATION_SCHEMA.STAGES
 WHERE STAGE_NAME = 'PIYO_STAGE';

そこで、 SHOW STAGES のドキュメントを確認してみると以下の記述が目に止まりました。

最大 10Kのレコードを返します。フィルタが適用されていても、10Kの制限を超えるレコードは返されません。
https://docs.snowflake.com/ja/sql-reference/sql/show-stages#usage-notes

もしかしてと思い、ステージの一覧を確認してみると EMBULK_ で始まるステージが1万件近くあることが確認できました。

SHOW STAGES LIKE 'EMBULK_%' IN SCHEMA "HOGE_DB"."FUGA_SCHEMA";
SELECT COUNT(*) -- 9979
 FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));

試しに EMBULK_ で始まるステージを1000件ほど削除してみると、無事 terraform plan が通るようになることも確認できました。

ということで今回の原因は、ステージが1万件を超えたため SHOW STAGES の結果が切り捨てられ、Terraform Provider 内でステージの情報が取得できなくなってしまったことが原因でした。

対応方法

Embulk を実行する度にステージが新規作成されていることが今回の事象に繋がったと考えられるため、Embulk 側でステージの削除を行なっていないか調査したところ、条件付きでステージの削除を行なっている箇所を見つけることができました。
https://github.com/trocco-io/embulk-output-snowflake/blob/f612567ed09445dd8970a21f8c47b43b267edbfc/src/main/java/org/embulk/output/SnowflakeOutputPlugin.java#L221-L223

どうやら delete_stage オプションが有効になっている場合にステージの削除を行なっているようです。
https://github.com/trocco-io/embulk-output-snowflake/blob/dd8d24a8100243370eae047613221cefc565ff90/src/main/java/org/embulk/output/SnowflakeOutputPlugin.java#L56-L58

ということで、既存の Embulk のファイルたちに delete_stage オプションを付与することで問題の恒久対応を行うことができました。

また、 delete_stage オプションは多くのユーザーに関係すると思われますが、 README にオプションの説明が存在していなかったため、説明を追加する PR も出してみました。

まとめ

今回の問題は、Embulk を実行するたびに作成されるステージが蓄積された結果、ステージが1万件を超えたため SHOW STAGES の結果が切り捨てられてしまい、 Terraform Provider 内でステージの情報が参照できなくなったことが原因でした。

delete_stage オプションの存在を知らない人の参考になれば幸いです。

スタフェステックブログ

Discussion