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

Terraform -> OpenTofu: итоги года миграции клиентских IaC-репозиториев

За год перевели все клиентские IaC-репозитории с Terraform на OpenTofu. Делимся чек-листом миграции и нюансами провайдеров Yandex Cloud и VK Cloud.

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

OpenTofu 1.8 выпустил поддержку provider functions и early evaluation переменных; экосистема активно растёт

Примерно год назад мы начали переводить первые клиентские репозитории с Terraform на OpenTofu. Не потому что очень хотелось - просто Hashicorp сменила лицензию, и вопрос «что дальше» встал конкретно. Сейчас все клиентские IaC-репозитории на OpenTofu, последний перевели в сентябре. Самое время зафиксировать что получилось, что было неприятно и где подводные камни именно для российских облаков.

Почему вообще переходили, если «работало»

Лицензия BSL 1.1 - это не запрет на использование, но это уже не open source. Для части клиентов это комплаенс-вопрос, для другой части просто принципиальная позиция. Для нас самих - нежелание зависеть от инструмента, условия использования которого могут измениться в следующем релизе без предупреждения.

OpenTofu к моменту начала нашей миграции уже вышел в 1.6 GA и показал себя рабочим. Совместимость с Terraform 1.5 была заявлена как полная, на практике - почти полная, с несколькими нюансами.

Чек-лист миграции репозитория

Мы в итоге пришли к следующей последовательности. Порядок важен: если поменять местами несколько шагов, получишь проблемы с state-блокировками или неожиданные drift-ы в плане.

1. Инвентаризация. Смотрим версию провайдеров в required_providers и наличие .terraform.lock.hcl. Если lock-файл есть и провайдеры зафиксированы на конкретных хешах для linux_amd64 - потребуется пересоздать его под OpenTofu, потому что хеши не совпадают.

2. Проверяем источники провайдеров. Если провайдер тянется из registry.terraform.io - переключаем на registry.opentofu.org. Большинство популярных провайдеров там есть, включая Yandex Cloud и VK Cloud (об этом отдельно ниже).

3. Убираем required_version с жёсткой привязкой к Terraform. Блок вида required_version = "~> 1.5" без указания источника работает, но лучше явно переписать под OpenTofu через .terraform-version или OPENTOFU_VERSION в CI.

4. Пересоздаём lock-файл. tofu providers lock с явным указанием платформ (-platform=linux_amd64 и остальных нужных). Коммитим новый .terraform.lock.hcl.

5. Тестовый tofu init + tofu plan. В CI добавляем флаг -detailed-exitcode чтобы план с нулём изменений не валил пайплайн. Первый plan после миграции должен показывать пустой diff - это индикатор что state читается корректно.

6. Проверяем backend-конфигурацию. S3-совместимые бэкенды (Yandex Object Storage, VK Cloud S3) работают без изменений. Если был использован terraform_remote_state data source - его тоже нужно обновить на opentofu_remote_state или убедиться, что он берёт state из OpenTofu-совместимого бэкенда.

7. Обновляем CI/CD. Меняем terraform на tofu в скриптах, обновляем Docker-образы или установочные шаги. Если использовался hashicorp/setup-terraform в GitHub Actions - переключаемся на opentofu/setup-opentofu.

Нюансы с Yandex Cloud провайдером

Провайдер yandex-cloud/yandex доступен в реестре OpenTofu без изменений. Технически он работает и с Terraform, и с OpenTofu - это один и тот же бинарник. Реальные проблемы были в другом.

Версионирование. Несколько репозиториев сидели на старых версиях провайдера с зафиксированным lock-файлом. После пересоздания lock-файла под OpenTofu стало удобно заодно обновить провайдер. Но обновление с 0.8x на 0.9x принесло ломающие изменения в ряде ресурсов - yandex_mdb_postgresql_cluster в частности. Пришлось сначала обновить провайдер на Terraform, проверить что план чистый, и только потом мигрировать на OpenTofu. Два отдельных коммита, не один.

Managed Service for Kubernetes в Yandex Cloud. Версия Kubernetes в ресурсе yandex_kubernetes_cluster принимает строку. Раньше некоторые конфигурации использовали version = "1.28" без явного platform_version. После обновления провайдера это начало показывать drift при каждом плане, потому что провайдер стал добавлять значения по умолчанию. Решение - явно добавить platform_version в state через tofu state или принять drift один раз и зафиксировать.

Нюансы с VK Cloud провайдером

С VK Cloud история чуть сложнее. Официальный провайдер vk-cs/vkcs в реестре OpenTofu есть, но некоторые клиенты использовали его в конфигурациях, где провайдер тянулся напрямую из GitHub через source = "github.com/vk-cs/terraform-provider-vkcs". Такой формат OpenTofu не понимает - нужен либо реестр, либо зеркало.

Решение: явно переключить source на registry.opentofu.org/vk-cs/vkcs. Версии там актуальные, лаг минимальный. Одному клиенту пришлось локально собрать провайдер и положить в ~/.terraform.d/plugins (для OpenTofu путь аналогичный, только директория называется ~/.opentofu/providers на некоторых установках) - это уже крайний случай для специфических изолированных сред.

OpenTofu 1.8 и что из него реально использовали

Параллельно с переездами OpenTofu не стоял на месте. В 1.7 появилось нативное шифрование state, которое мы начали раскатывать на ряде проектов. В 1.8 добавились provider functions - возможность вызывать функции, экспортируемые провайдером, прямо в HCL.

На практике provider functions пока использует мало провайдеров - Yandex Cloud и VK Cloud на момент написания этого функцию не добавили. Но уже интересно смотреть на провайдер AWS, где появилось несколько утилитарных функций для работы с ARN и политиками. Для нас это пока «знаем, следим», а не «применяем».

Ещё в 1.8 - early evaluation переменных: переменные из var.* теперь можно использовать в provider блоках без workaround-ов через locals. Это закрывает один давний раздражитель для динамических конфигураций с несколькими регионами или accounts.

Что в итоге

Миграция в целом прошла спокойно - основные сложности были не в совместимости OpenTofu с Terraform, а в накопившихся проблемах самих репозиториев: незафиксированные версии провайдеров, устаревшие ресурсы, жёсткие привязки к конкретным облачным API. Миграция просто вынудила разобраться с тем, что висело без внимания.

Если у вас есть IaC-репозитории, которые ещё на Terraform, - особого смысла откладывать нет. Два-три часа на репозиторий средней сложности, включая тест в CI. Больнее всего там, где провайдеры сидят на старых версиях или источники прописаны нестандартно.

Контакт

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

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