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 側でステージの削除を行なっていないか調査したところ、条件付きでステージの削除を行なっている箇所を見つけることができました。
どうやら delete_stage
オプションが有効になっている場合にステージの削除を行なっているようです。
ということで、既存の Embulk のファイルたちに delete_stage
オプションを付与することで問題の恒久対応を行うことができました。
また、 delete_stage
オプションは多くのユーザーに関係すると思われますが、 README にオプションの説明が存在していなかったため、説明を追加する PR も出してみました。
まとめ
今回の問題は、Embulk を実行するたびに作成されるステージが蓄積された結果、ステージが1万件を超えたため SHOW STAGES
の結果が切り捨てられてしまい、 Terraform Provider 内でステージの情報が参照できなくなったことが原因でした。
delete_stage
オプションの存在を知らない人の参考になれば幸いです。
Discussion