ADG Оставить заявку
Блог Автоматизация 5 мин чтения

Terraform 0.11: интерактивный apply и preview HCL2 - что это значит для модульной инфраструктуры

Обновляем Terraform до 0.11 на managed-проектах: новый интерактивный apply упрощает работу команды, preview HCL2 показывает - в 0.12 нас ждёт рефакторинг модулей.

Контекст момента

Terraform 0.11 - улучшенный интерактивный UI с обязательным подтверждением apply, флаг -target для точечного применения, preview HCL2, улучшенная поддержка count с list-переменными

Terraform 0.11 вышел в начале ноября. Мы уже прогнали обновление на нескольких managed-проектах - там где инфраструктура живёт в git и применяется через CI. Расскажем что поменялось на практике и почему changelog про HCL2 нас немного насторожил.

Интерактивный apply теперь не пропустить

Самое заметное изменение для тех кто запускает terraform руками - это переработанный UI при apply. Раньше terraform apply сразу выполнял план, если не передать -input=false или не использовать сохранённый план-файл. Сейчас 0.11 всегда показывает что будет сделано и требует явного yes перед выполнением. Без подтверждения - нет apply.

На первый взгляд мелочь. На деле это закрывает целый класс инцидентов: «запустил apply в prod, думал что в staging». Или «хотел посмотреть plan, нажал не ту команду». Теперь план всегда перед глазами, и есть секунда чтобы прочитать что именно будет уничтожено.

Для наших пайплайнов в GitLab это изменение прошло безболезненно - там apply всегда с -auto-approve или через сохранённый plan-файл. А вот для инженеров которые иногда работают локально - это реально удобнее.

Флаг -target: точечное применение

В 0.11 официально задокументирован и отполирован флаг -target, который позволяет применить изменения только к конкретному ресурсу или модулю:

terraform apply -target=aws_instance.web
terraform apply -target=module.database

Флаг существовал раньше, но работал нестабильно с модулями. Теперь он нормально обрабатывает граф зависимостей внутри таргетированного ресурса.

Применений несколько. Отладка нового ресурса - когда пишешь новый модуль и хочешь проверить только его, не трогая остальную инфраструктуру. Точечное исправление - когда один ресурс разъехался с действительностью и нужно его пересоздать или обновить без полного apply. Ступенчатое применение - когда изменение большое и хочется раскатывать по частям.

Оговорка: злоупотреблять -target не стоит. Если применять изменения кусками, state начинает расходиться с реальным планом, и потом полный apply может удивить. Инструмент для исключительных случаев, не для рабочего процесса.

count с list-переменными стал нормально работать

В 0.11 поправили поведение count когда значение вычисляется из list-переменной. До этого была характерная проблема:

variable "availability_zones" {
  type = "list"
}

resource "aws_subnet" "private" {
  count             = "${length(var.availability_zones)}"
  availability_zone = "${element(var.availability_zones, count.index)}"
  # ...
}

В старых версиях count вычислялся на этапе plan, и если список приходил из data source или другого ресурса (значение известно только после apply), Terraform падал с ошибкой вроде «value of count cannot be computed». В 0.11 это сценарий лучше обрабатывается для большинства случаев с переменными. Не решено полностью, но стало значительно тише.

У нас в одном из модулей была ровно такая конструкция для создания подсетей по количеству AZ - теперь работает без танцев с дополнительными переменными.

HCL2 preview: что нас ждёт в 0.12

Вот здесь интереснее. В релизе 0.11 HashiCorp показали preview следующей версии языка - HCL2. Это не просто косметические изменения, это другой синтаксис.

Несколько вещей которые сразу бросились в глаза из документации:

Выражения без ${} - в HCL2 можно писать count = length(var.availability_zones) вместо count = "${length(var.availability_zones)}". Кавычки со скобками у нас везде, и их придётся убирать.

Типизированные переменные - вместо type = "list" будет type = list(string). Типы станут реальными типами, а не строками.

For-выражения - появится нормальный for для преобразования коллекций, что сейчас приходится делать через null_resource и local_file или громоздкие конструкции с element и count.

Обязательный рефакторинг модулей - обратной совместимости синтаксиса нет. Это значит что переход на 0.12 будет не «прочитать changelog и обновить бинарь», а полноценный рефакторинг всех конфигураций.

Масштаб работы зависит от объёма кодовой базы. У нас несколько проектов с десятками модулей - это серьёзный рефакторинг. HashiCorp обещают написать migration guide и автоматизированный конвертер, но это обещания, пока смотрим на preview.

Пока же 0.11 - это стабильный релиз на котором можно спокойно работать. Новых возможностей в HCL2 нет, только preview документация.

Как обновлялись

Обновление прошло без неожиданностей. terraform 0.11upgrade прошёлся по конфигурациям и добавил обязательные кавычки вокруг типов переменных - в 0.11 это стало требованием, а не просто рекомендацией:

# было (0.10 принимал и так и так)
variable "count" {
  type = string
}

# стало (0.11 требует кавычки)
variable "count" {
  type = "string"
}

Для большинства конфигураций upgrade-команда сделала всё сама. Просмотрели diff, зафиксировали в git, прогнали план - всё чисто.

Отдельно проверили что terraform validate проходит для всех компонентов до обновления prod. Там нашлась одна конструкция с count в модуле которая давала предупреждение - поправили до переключения.

Что в итоге

0.11 - это добротный релиз с правильными приоритетами. Принудительное подтверждение apply - та мелочь которая реально снижает риск случайного изменения. Починенный count с list-переменными убирает несколько типичных костылей в модулях.

Главный вывод из релиза - не из самого 0.11, а из preview HCL2. Если у вас есть кодовая база конфигураций Terraform, начинайте держать в голове что переход на 0.12 будет не апгрейдом бинаря, а рефакторингом. Лучше знать об этом заранее чем столкнуться когда 0.12 уже вышел и нужно мигрировать срочно.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.