#moved-block-vs-state-mv
Зачем нужен `moved {}` блок и чем он лучше `terraform state mv`?
Что отвечать
`moved {}` объявляет переезд ресурса в HCL: «то, что было `module.old.x`, теперь `module.new.x`». На plan Terraform видит блок и переносит запись в state как часть change set, без destroy+create. Главное отличие от `state mv`: декларативность. Блок коммитится в репо, ревьюится в PR, виден в `terraform plan` коллеге. После того как все коллеги сделали `apply` - можно удалить блок через несколько релизов. `state mv` мутирует state локально, в PR никак не отражается, коллегам нужно вручную делать то же самое - источник рассинхрона.
Что хотят услышать
Senior должен: - назвать что moved-блок появился в 1.1 как штатный механизм рефакторинга - объяснить «грейс-период»: блок остаётся в HCL несколько релизов пока все среды его применят, потом удаляется - сказать что moved работает только для адресов: переименовать ресурс, перенести в child-модуль, поменять префикс. Не работает для смены типа ресурса или провайдера - упомянуть что один блок описывает переезд одного ресурса; для массового рефакторинга - несколько блоков, ревью требует внимания
Подводные камни
- ✗ Использовать `state mv` в команде - твой состояние знает, состояние коллег не знает; на их apply увидят destroy+create
- ✗ Удалить moved-блок до того как все среды его проиграли - неприменённые ещё среды получат destroy+create
- ✗ Думать что moved может изменить тип ресурса (`aws_s3_bucket` → `aws_s3_bucket_v2`) - не может; для смены типа нужен import + rm
Follow-up
- ? Сколько релизов держать moved-блок в HCL?
- ? Как переименовать ресурс между провайдерами (`aws` → `awscc`)?
- ? Что произойдёт если два moved-блока противоречат друг другу?
Глубина в базе знаний