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

OpenTofu 1.7: перевели первый enterprise-проект с Terraform и делимся чеклистом миграции

OpenTofu 1.7 вышел с provider-defined functions и улучшенным state encryption. Рассказываем, как мигрировали state с Terraform без потерь и что потребовало правок в CI/CD.

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

OpenTofu 1.7 вышел с поддержкой provider-defined functions и улучшенным state encryption - форк Terraform набирает корпоративных пользователей

OpenTofu 1.7 вышел на прошлой неделе, и это первый релиз, который мы восприняли не как «смотрим в сторону», а как «уже переходим». У нас как раз дозрел клиент, которому надо было принять решение по Terraform: лицензия BSL продолжает создавать вопросы с юридическим отделом, а инфраструктура немаленькая - несколько сотен ресурсов, несколько окружений, CI/CD на GitLab.

Миграция заняла несколько дней с подготовкой и тестированием. State дошёл до OpenTofu без потерь, CI/CD потребовал минимальных правок. Делимся тем, что реально пришлось делать, а не тем, что написано в release notes.

Почему именно сейчас

Hashicorp перевёл Terraform на BSL в августе 2023-го. С тех пор OpenTofu - форк под MPL-2.0 - развивался под крылом Linux Foundation и постепенно набирал enterprise-пользователей. Версия 1.7 добавила две вещи, которые нас интересовали.

Provider-defined functions - возможность для провайдеров экспортировать собственные функции, которые можно использовать прямо в конфигурации. До этого часть логики вынуждала писать либо костыли на locals, либо тащить external data source. Для конкретного клиента это важно: у него самописный провайдер для внутренней платформы, и авторы провайдера уже смотрели на эту возможность.

State encryption - встроенное шифрование state-файлов с несколькими backend-ами для ключей (passphrase, AWS KMS, GCP KMS). В Terraform этого нет - state в S3 шифруется только на уровне bucket-а, а содержимое доступно всем, у кого есть доступ к бакету. Для клиента с требованиями к хранению секретов это закрывало реальный вопрос, а не просто галочку в чеклисте.

Что на деле требует внимания при миграции

Официальная документация OpenTofu про миграцию с Terraform написана оптимистично: «замените бинарник, запустите tofu init, готово». В целом это правда - но дьявол в деталях.

Версия провайдеров. OpenTofu использует собственный реестр (registry.opentofu.org). Большинство популярных провайдеров там есть, но не все и не всегда в последней версии. Перед миграцией стоит пройтись по всем required_providers и убедиться, что нужная версия доступна. У клиента один из провайдеров пришлось зафиксировать на версии чуть старше, чем использовалась с Terraform - в реестре OpenTofu этой версии не оказалось. Это не катастрофа, но лучше знать заранее.

Синтаксис terraform блока. В конфигурации нужно заменить блок terraform на terraform с required_version под OpenTofu (или оставить как есть - OpenTofu понимает оба варианта). Важнее другое: если в конфигурации используется terraform.io как source для провайдеров, нужно проверить, замапился ли он на opentofu-реестр. tofu init делает это автоматически, но только если провайдер есть в реестре.

State-файл. Формат state в OpenTofu 1.7 обратно совместим с Terraform. tofu state list после tofu init показал все ресурсы - ничего не потерялось. tofu plan после этого дал нулевой diff, что и было главным критерием успеха на этом этапе.

CI/CD. В GitLab-пайплайне пришлось заменить образ hashicorp/terraform на ghcr.io/opentofu/opentofu и подправить переменную с именем бинарника (где она явно прописывалась). Всё остальное - команды, флаги, переменные окружения - идентично. TF_VAR_* OpenTofu тоже понимает. Время на правки CI/CD - час, включая тестирование.

Чеклист перехода

Порядок, который сработал у нас:

1. Инвентаризация провайдеров. Список всех required_providers с версиями, проверка наличия в registry.opentofu.org. Особое внимание на нестандартные и внутренние провайдеры.

2. Тестовое окружение первым. Мигрировать сначала dev или staging, не prod. Запустить tofu init, tofu plan, убедиться в нулевом дифе.

3. Резервная копия state. Перед любой операцией с prod-state - бэкап. S3 versioning должен быть включён в любом случае, но явный cp перед миграцией не лишний.

4. tofu init -migrate-state. На remote backend (S3 + DynamoDB) - именно этот флаг. Без него tofu init ругается на существующий state от другого инструмента.

5. tofu plan в режиме read-only. Убедиться, что план пустой. Любой diff - повод разбираться, а не применять.

6. Обновление CI/CD. Заменить образы и бинарник. Прогнать пайплайн в dry-run режиме.

7. Переключение prod. Последовательно, не параллельно с Terraform. Два инструмента, работающих с одним state, - это путь к конфликтам.

State encryption: настроили, но осторожно

В 1.7 мы включили state encryption для нового окружения, которое разворачивалось с нуля. Для уже существующего state мигрировать шифрование в продакшне не стали - это отдельная операция, и документация честно предупреждает о необходимости тщательного тестирования. Оставили на следующий спринт.

Сам механизм выглядит разумно: конфигурация шифрования описывается в блоке encryption внутри terraform (да, блок всё ещё называется terraform в синтаксисе), ключи берутся из KMS или из passphrase. Passphrase через переменную окружения - вариант для тех, кто не хочет тащить AWS KMS. Для корпоративного использования с нормальным управлением секретами KMS предпочтительнее.

Что остаётся открытым

OpenTofu 1.7 - вполне рабочий инструмент для enterprise-перехода с Terraform. Экосистема провайдеров ещё не такая полная, как у Hashicorp-реестра, и это реальное ограничение для тех, кто использует что-то нестандартное. Tooling вокруг - Atlantis, Terragrunt, Spacelift - добавляет поддержку OpenTofu, но степень зрелости разная.

Сопровождение инфраструктуры в нашем случае означает и ответственность за инструментарий. Переход на форк с другой лицензией - решение не только техническое. Но если инфраструктура уже на Terraform и лицензионные вопросы давят, OpenTofu 1.7 выглядит как вполне взрослый вариант для перехода - не эксперимент.

Контакт

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

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