Ручное изменение в облаке: что показывает refresh-only в Terraform и OpenTofu

Во время инцидента оператор вручную изменил настройку облачного ресурса. Через день обычный plan предлагает вернуть старое значение из HCL. Команда хочет сохранить экстренное исправление, но опасается, что любой apply сразу начнёт менять инфраструктуру. Здесь помогает разделить три представления: желаемую конфигурацию, сохранённый state и фактический объект.

Refresh-only строит план обновления state и корневых outputs по прочитанным удалённым объектам. Он не предлагает привести удалённый объект к HCL в рамках этого режима. Но принятие такого плана само по себе не переписывает желаемую конфигурацию.

Конкретный пример с тегом

Предположим, уже управляемый S3 bucket объявлен так. Это фрагмент существующей конфигурации, где provider, backend и сам объект уже настроены. Не создавайте новый bucket по этому имени ради чтения примера.

resource "aws_s3_bucket" "archive" {
  bucket = "existing-training-archive-12345"
  tags = {
    Owner = "platform"
  }
}

В облаке Owner вручную изменили на incident-team. В state может оставаться platform, а в HCL оно осталось точно. Обычный plan по умолчанию читает фактическое состояние и сравнивает его с конфигурацией, поэтому может предложить обновление Owner обратно на platform. Важно увидеть не только сообщение о внешнем изменении, но и последующие действия плана.

Прочитаем отклонение отдельно от исправления

Выполняйте команды своего инструмента с привычными backend, workspace и переменными. Plan обращается к реальным API с текущими credentials, поэтому запускайте его в разрешённом контексте.

terraform plan -refresh-only -out=observed.tfplan
terraform show -no-color observed.tfplan
tofu plan -refresh-only -out=observed.tfplan
tofu show -no-color observed.tfplan

В этом плане рассматривается запись наблюдённого Owner в состояние и возможное изменение outputs. Применение проверенного refresh-only плана обновит state, не возвращая тег к platform в облаке. Но следующий обычный plan снова сравнит incident-team с HCL platform и может предложить возврат. Это центральная граница режима.

Refresh-only Terraform доступен с версии 0.15.4. Соответствующий режим есть и в OpenTofu. Не смешивайте его с -refresh=false: второй флаг отключает чтение изменений и способен скрыть нужное отклонение.

Решим, какое значение теперь желаемое

Если incident-team должно остаться, измените HCL на это значение и проверьте новый обычный plan. Если ручная правка была временной, сохраните platform и согласуйте возврат. В обоих случаях решение о желаемом состоянии принимается отдельно от регистрации факта.

Иногда одним полем намеренно управляет другая система. Тогда можно рассмотреть ignore_changes для этого поля с понятным владельцем. Но добавление ignore_changes лишь ради исчезновения неудобного diff оставит ответственность неопределённой. Через месяц никто не сможет объяснить, какая система должна восстанавливать значение после сбоя.

Не всякое отсутствие объекта означает удаление

Если API не видит прежний ресурс, сначала проверьте аккаунт, регион и права. Неверный provider context способен выглядеть как отсутствие объекта. Refresh-only в таком случае может предложить убрать привязку из state; принятие неверного наблюдения усложнит последующее управление.

Для действительно удалённого вручную ресурса обычный plan может предложить восстановление, а refresh-only — отразить отсутствие в state. Это разные действия с разными последствиями. Сопоставьте ID из состояния с реальной системой прежде, чем одобрять любой из вариантов.

Закончим новым обычным планом

Сохраните контекст экстренной правки: что изменили, зачем и какое значение теперь должно поддерживаться кодом. Затем выберите принятие или возврат, обновите HCL при необходимости и постройте обычный plan. Он должен показывать только согласованные действия.

Так refresh-only становится инструментом разбора рассогласования, а не универсальной кнопкой «согласиться со всем». Команда отдельно понимает, что сейчас есть в облаке, что записано в state и что следующий apply будет считать желаемым результатом.

Ещё по теме

Продолжить изучение

Хотите управлять инфраструктурой через код и понимать последствия изменений? Plan, state, модули и работа с существующими ресурсами — темы программы «Terraform и OpenTofu: инфраструктура как код».

Продолжить на практике

  • Terraform и OpenTofu: инфраструктура как код ↗

    Описывайте инфраструктуру в коде, проверяйте изменения до применения и работайте со state без сюрпризов. HCL, модули, remote state, импорт, CI и различия Terraform/OpenTofu — на воспроизводимом учебном окружении.