План изменений и жизненный цикл ресурса
В «Контуре» уже объявлены образ и контейнер Nginx. Теперь рассмотрим план изменений — документ, который соединяет конфигурационное намерение с возможными действиями провайдера. Мы будем читать будущую последовательность, не выполнять её. Сохранённый план полезен именно тогда, когда человек понимает, какие объекты и каким способом изменятся, а не просто ищет в выводе зелёный цвет.
Текущий каталог содержит исходники двух ресурсов. Но один и тот же набор файлов может привести к разным планам: в новой лаборатории объекты отсутствуют, в рабочей папке они уже связаны со state, а после ручного удаления контейнера один объект исчез. Terraform учитывает эти обстоятельства при сравнении. Поэтому план нельзя корректно обсуждать, не назвав рабочую копию, выбранное состояние и Docker endpoint.
Создание, изменение и замена
Создание вводит новый объект управления. Обновление изменяет существующий объект, если провайдер умеет сделать это без пересоздания. Замена означает удаление старого экземпляра и создание нового. Для контейнера изменение некоторых аргументов может требовать именно замены. Последствие существенно: процесс остановится, идентификатор изменится, а данные внутри записываемого слоя контейнера могут потеряться. Красивое оформление diff не делает такую операцию безобидной.
Поле имени задаёт идентичность Docker-контейнера, но адрес Terraform сохраняется при редактировании аргумента name. Если объявление всё ещё называется docker_container.web, инструмент рассматривает изменение того же ресурса. Переименование самого локального блока — другая операция: меняется адрес в конфигурации. Без указания переноса Terraform может воспринять её как исчезновение старого объявления и появление нового. Работа с moved понадобится при выделении модуля.
Команды для отдельной самостоятельной работы читателя; при написании не выполнялись:
terraform init
terraform plan -out=local.tfplan
terraform show local.tfplan
Команда terraform plan -out=local.tfplan предназначена для сохранения предлагаемой операции. Файл содержит больше данных, чем текстовый вывод: в том числе значения, использованные при расчёте. Считать его обычным публичным артефактом неправильно. Его нельзя прикладывать к статье или коммитить рядом с исходниками без понимания содержимого. В нашей лаборатории секретов нет, но привычка разделять типы файлов должна появиться раньше настоящих паролей.
Обзор до самостоятельного применения
terraform show local.tfplan позволяет снова прочитать сохранённый план. При таком обзоре полезно назвать каждую затронутую сущность: образ, контейнер, порт и имя. Строка о двух создаваемых ресурсах не объясняет, на каком daemon они возникнут и кому будет доступен порт. Проверка endpoint и адреса привязки остаётся отдельной частью решения. План отражает знания провайдера, а не намерения оператора, оставшиеся только в голове.
Если позже читатель решит применить именно этот план, команда с файлом отличается от свободного terraform apply. В свободном варианте инструмент рассчитывает новое предложение; в варианте с файлом используется подготовленный набор действий и его ограничения. Однако сохранённый файл не гарантирует неизменность мира между обзором и исполнением. Состояние могло измениться, контейнер могли удалить, доступ к Docker мог исчезнуть. При отказе не надо обходить проверку вручную редактированием state.
Сравните три ситуации. В первой конфигурация, состояние и Docker согласованы: ожидается отсутствие нужных изменений. Во второй изменён внешний порт: план должен показать изменение или замену контейнера в соответствии со схемой провайдера. В третьей изменён только комментарий в .tf: ресурсное намерение осталось тем же. Эта классификация помогает не путать редакционное изменение файла с изменением инфраструктуры.
Почему план не равен проверке приложения
Terraform способен предложить корректный с точки зрения своей модели контейнер, в котором приложение возвращает ошибку. Например, ресурс создан, процесс формально запущен, но HTML неправильно закодирован или нужный маршрут отсутствует. Проверка инфраструктурной разницы и проверка поведения HTTP-сервера отвечают на разные вопросы. В этом курсе мы отдельно описываем ожидаемые ответы, но не заявляем, что они были получены при написании материалов.
Более тонкий случай связан с портом. Провайдер может обнаружить конфликт во время создания контейнера, хотя предыдущий план выглядел допустимым. План не резервирует внешний порт заранее. Между его расчётом и применением другой процесс способен занять адрес. Поэтому фраза «план согласован» означает разрешённое намерение, а не обещание успешного запуска при любых внешних изменениях. Решение ошибки должно начинаться с выяснения нового факта.
Не используйте флаг автоматического подтверждения как способ избавиться от чтения вывода. В лаборатории объекты маленькие, но тот же приём легко переносится к важным базам и сетям. Кроме того, автоматическое подтверждение не убирает возможность замены контейнера. Для учебного проекта удобнее сохранить читаемый план и явно обсуждать удаление или пересоздание. Список допустимых действий может быть коротким: новый образ и один локальный контейнер с loopback-портом.
Представим, что коллега прислал обновление имени с kontur-web на kontur-home. Уточнение назначения кажется косметическим, однако Docker-имя может участвовать во внешних командах и наблюдении. До применения спросите себя, кто использует старое имя и что случится с текущим идентификатором. Ответ может привести к отказу от переименования или к отдельной миграционной заметке. Такой разбор ценнее механической проверки числа плюсов и минусов.
Сохранённый план относится к конкретному моменту и конкретному рабочему состоянию. Не копируйте его в другую папку и не предлагайте применять на другом компьютере как универсальный рецепт создания «Контура». Переносимый учебный результат этого урока — понимание действий, исходники и порядок обзора. Следующий урок добавит входные параметры и собственный HTML, чтобы настройка сайта была явной частью конфигурации, а не случайным редактированием нескольких строк.
Обсуждение плана в команде
Полезная запись обзора называет исходную цель: «добавляем локальный сайт без публичного доступа», а затем сопоставляет ей действия. Если план неожиданно удаляет сеть другого окружения, число создаваемых контейнеров уже не является достаточным аргументом одобрения. Надо остановиться на причине несоответствия и проверить выбранный корень. Обзор предназначен для принятия решения, поэтому результат должен быть понятен человеку, который не писал блоки ресурсов.
Предложение изменения образа требует другого обсуждения, чем смена комментария. У образа есть источник, платформа и поведение процесса; комментарий помогает читателю исходников. Объединяя такие изменения, легко пропустить настоящую замену среди редакционной правки. Лучше мысленно разложить разницу на независимые причины. Это не требование создавать много искусственных коммитов, а способ удержать связь между каждой строкой конфигурации и конкретным последствием.
Оглавление серии, общая подборка и полный архив исходников. Для этого урока выберите lesson-03.
Первичные источники: Версии Terraform, Учебник Terraform и Docker, Схема Docker container 3.6.2, Схема Docker image 3.6.2, Адреса и moved, Локальный backend, Import, Refresh-only plan.
Редакционный статус: локальный черновик. Учебные команды, приложение и проверки не запускались; описанные результаты ожидаемые. Профиль версий закреплён, разрешённый lockfile не создавался.