notes mizzy.org

import / removed / moved は現実を動かさずに帳簿だけを書き換える

解釈 出典: explorations/2026-04-26-…/chapter-4 作成

IaCの差分エンジンは「コードとstateがずれていたら現実を動かして揃える」機械である。リソースの名前を変えればstateに無い名前が現れ、Createが出る。旧い名前はdesiredから消えるのでDeleteが出る。つまり素朴に作ると、コードの整理がそのまま本番の作り直しになる。

import / removed / moved はこの結びつきを切る。3つともstateだけを書き換えて、クラウド側のAPIを一切叩かない

素朴に名前を変えると コード state Create + Delete 本番が作り直る state blocks を書くと コード state Create / Delete は 撤回される 現実は動かない
ブロックstateに対して現実に対して
import既存リソースをstateに登録する何もしない(既にある)
removedstateから登録を外す何もしない(残り続ける)
moved登録のアドレスを付け替える何もしない(同じ物)

なぜこれが重要か

コードの構造と、動いている実体の寿命が分離できるからである。

この分離が無いと、リファクタリングの費用が「エディタ上の手間」ではなく「本番の停止時間」になる。名前が気に入らないだけでDBが作り直されるなら、誰も名前を直さない。モジュールを切り直すとVPCが消えるなら、構造は腐ったまま凍結される。コードの整理にリスクが乗った瞬間、整理されなくなる。

裏返せば、この3つは「あとで直せる」を保証する機構である。IaCは一度書いたら長く生きるコードなので、最初の設計が最適であることより、後から作り替えられることのほうが効いてくる

import はさらにもう一方向を開く。IaCの外で生まれた実体を、後から管理下に入れられる。 これが無いと「最初からIaCで作ったものしか管理できない」ことになり、手で作った既存環境は永久に手作業のままになる。移行の経路がある。

効果としての位置づけ

Carinaではこの3つも Effect の一種として、他の7種と同じ列に並ぶ。ただし出自が違う。差分エンジンが選ぶのは Read / Create / Update / Delete / Wait の5種で、Import / Remove / Move は差分エンジンが一切出さない。ユーザーが書いたブロックから、plan生成後の後処理(add_state_block_effects)が付け足す。

この後処理は付け足すだけでなく、差分エンジンが出した命令を撤回するremoved の対象に対応するDeleteを消し、import の対象に対応するCreateを消す。撤回こそがこの機構の本体である — 放っておけば差分エンジンが出してしまう「現実を動かす命令」を、ユーザーの宣言で取り下げている。

そして撤回された結果もまたplanに載る。planは効果の列という平らな値なので、「stateだけが動いて現実は動かない」ことがapplyの前に目で確認できる。帳簿の書き換えが黙って起きるのではなく、命令として明示される。

危うさも同じ場所から来る

現実を動かさないということは、stateと現実がずれる方向にも動かせるということでもある。removed を書けばリソースは残ったまま管理から外れ、誰も面倒を見ない実体になる。import のidを間違えれば、別の実体を掴んだまま以後のplanが嘘をつく。

差分エンジンの出す命令は「stateを現実に近づける」方向にしか動かないので間違えても収束するが、state blocksはその保証の外側にある。ユーザーが直接命令を書いている以上、正しさの根拠はユーザーの意図だけである。planに出ることが唯一の防波堤になる。

#state #リファクタリング #plan #iac