tfstateが知らぬ間にDriftしてしまうことに対策を考える
なぜ発生するか
- IaC外での操作
- 別のtfstateが更新され、そのtfstateのoutputを参照しており、参照先のtfstateを再plan/applyされず放置される場合
- moduleの更新やresourceのバージョンを上げた際に、実行されなかった場合
- わからんけどなぜか発生する
別のtfstateが更新され、そのtfstateのoutputを参照しており、参照先のtfstateを再plan/applyされず放置される場合
今回はこれに言及する
あるtfstateAが別のtfstaeBのoutputを参照していて、Bをapplyした際にAもapplyしようとするのは結構たいへん
なぜなら、Bのtfstateには参照されている情報がないから。
じゃあどうしよう。terraform cloudではRemote state sharing
があり、明示的に参照される側でoutputを明示しないとだめ。
だけど、実行まではしてくれないし、循環参照とかでCIが実は24時間働いてました、なんてリスクもある
ここは力技的にやるしかないかな。
ディレクトリを全走査して、厳格なルールの下、dependency mapのようなものを構築するか、
terragruntで明示的な依存関係を定義してやるか
今回の課題は
動的に決まる依存関係先のtfstateの再実行をCIでどのように実装していくか
あるtfstateでは以下のような依存関係を持っていたとする。
BはAのoutputを引いており、C1とC2はBのoutputを引いている。
この場合、Aをapplyした場合Bも再apply、Bをapplyした場合C1とC2の再apply必要になる
A ← B ← C1
↖ C2
これをCIで実装するのはけっこう大変
楽な案:
定期的に全tfstaeをplanしてみる。
多少の危険性はあるが、ないよりまし。
例えば1時間に1回全tfstaetをplanして、差分があったらオペレーターに通知
ただ、1時間に1回しか依存関係の深さを解決しないので、C1とC2が適正になるのは2時間後
これを許容するかどうするか迷うとこだけど、シンプルで実装も容易。
ciにscheduled_workflowを加えるだけ
かっちりやる案:
applyしたあとに、👆で言及してたDependencyMap(tfstate群の依存関係を表すデータ)から次にplanが必要なtfstateをあぶり出す。
で、Actionsのon.workflow_callなどを駆使して、再帰的に呼び出す。
呼び出す処理には、
- planして、差分がなければ終了(変化がなければ、その次のtfstateにも影響はないので終了)
- 差分があれば、applyして(必要によっては、オペレーターに通知)、次のtfstateをon.workflow_callで再帰呼び出し
ループ検出的な機構は必要かもね