Как стать автором
Обновить

tenv — универсальный менеджер версий для Terraform-стека

Уровень сложностиПростой
Время на прочтение9 мин
Количество просмотров287

Когда в 2023 году появился OpenTofu, его моментально подхватило сообщество: идея полностью открытой альтернативы Terraform на тот момент выглядела свежо и многообещающе. Многие захотели попробовать его в деле — но очень быстро столкнулись с типичной проблемой: а как безболезненно переключаться между OpenTofu и Terraform? 

На первый взгляд всё казалось простым: установи два бинарника через любой пакетный менеджер — и готово. Но уже через пару месяцев активного развития OpenTofu, когда компании начали массово делать внутренние POC по миграции, стало очевидно: различий между OpenTofu и Terraform с каждой версией становится всё больше (часть из них хорошо видна, например, на cani.tf) и управлять разными версиями разных инструментов становиться все сложнее.

Именно тогда мы увидели нишу: менеджер версий, заточенный не просто под Terraform, а под весь Terraform-стек, включая OpenTofu. Да, на рынке уже были популярные инструменты вроде tfenv, tfswitch, asdf — но никто из них не собирался добавлять полноценную поддержку OpenTofu.

Всё началось с GitHub issues tfenv (tfenv#409, tfenv#411), где долго и активно спорили о поддержке OpenTofu — и в итоге ни к чему не пришли. Тогда Николай Мишин (@zombi_man) сделал форк tfenv под названием tofuenv — так и родилась команда tofuutils.

Форк работал хорошо и набирал популярность, но довольно быстро стало ясно: основная боль — не просто переключение версий, а переключение между разными инструментами. Мы встали перед выбором: пытаться добавить всё в один менеджер... или написать новый с нуля.

Выбрали второе. И не пожалели. После делательного анализа и очень подробного знакомства с tfenv оказалось, что это набор довольно запутанных Bash-скриптов, которые сложно поддерживать, особенно вне Linux-среды. А между тем популярность Terraform-стека на Windows и других ОС только росла.

Спустя пару дискуссий внутри сообщества мы доформировали команду и начали писать новый инструмент на Go. Так появился tenv: кроссплатформенный, расширяемый, и с самого начала заточенный под Terraform, OpenTofu и всё, что между ними.

Технологический стек

Почему Go? Всё просто: мы активно работаем с инфраструктурой, и Go давно стал для нас основным инструментом автоматизации. Высокая производительность, компилируемость и удобная экосистема сделали его очевидным выбором.

К тому же, на момент начала разработки tenv мы уже имели солидный опыт написания кода на Go. А во время обсуждений в сообществе OpenTofu познакомились с ещё одним Go-разработчиком, который как раз начал делать похожий инструмент. После короткого обсуждения решили объединить усилия и собрать всё в одном репозитории — так появилась первая версия tenv.

Универсальный менеджер версий: что такое tenv

tenv — это кроссплатформенный CLI-инструмент и по совместительству Go-библиотека для управления версиями популярных IaC-инструментов: OpenTofu, Terraform, Terragrunt, Atmos и Terramate.

Он позволяет легко устанавливать, переключать и использовать нужные версии IAC-инструментов как в локальной среде, так и в CI/CD пайплайнах.

На данный момент поддерживаются все актуальные операционные системы: Linux, Windows, macOS, OpenBSD, FreeBSD и Solaris

Также, особое внимание мы уделили удобству установки — tenv доступен через большинство популярных пакетных менеджеров: Homebrew, MacPorts, apk, pacman, AUR, nix, Scoop, Chocolatey, Snap и другие, включая установку через .deb и .rpm пакеты.

Быстрый старт

Если запустить tenv без аргументов - откроется интерактивный режим, в котором можно управлять всеми поддерживаемыми инструментами.

Интерактивный режим
Интерактивный режим

Для автоматизации, скриптов и CI/CD предусмотрен неинтерактивный режим с удобным интерфейсом: tenv <tool_alias> <action>.

Примеры алиасов и переменных окружения:

Tool alias

Environment variable prefix

Tool

terraform

TFENV

Terraform

tofu

TOFUENV

OpenTofu

tf

TFENV

Terraform/OpenTofu

tg

TG

Terragrunt

atmos

ATMOS

Atmos

tm

TM

Terramate

Примеры использования

Получить Список доступных версий OpenTofu:

$ tenv tofu list-remote

Установить конкретную версию OpenTofu:

$ tenv tofu install 1.9.1

Установить конкретную версию Terraform через зеркало от Яндекса:

$ export TFENV_REMOTE=https://hashicorp-releases.yandexcloud.net

$ tenv terraform install 1.5.3

Переключиться на нужную версию Terraform:

$ tenv terraform use 1.6.5

Проверка текущей активной версии Terraform:

$ tenv terraform list

  1.5.6 (never used)

* 1.5.7 (used 2025-05-16, set by /Users/kvendingoldo/.tenv/Terraform/version)

  1.9.8 (used 2024-12-09)

Удаление неиспользуемых версий Terraform:

$ tenv terraform uninstall

Если в каталоге проекта есть файл .tool-versions, tenv автоматически определит и установит нужные версии:

$ cat .tool-versions
terraform 1.5.6

$ tenv terraform install
Resolved version from /tmp/example/.tool-versions : 1.5.6

Installing Terraform 1.5.6

Fetching release information from https://releases.hashicorp.com/terraform/1.5.6/index.json

Downloading https://releases.hashicorp.com/terraform/1.5.6/terraform_1.5.6_darwin_arm64.zip

Downloading https://releases.hashicorp.com/terraform/1.5.6/terraform_1.5.6_SHA256SUMS

Downloading https://releases.hashicorp.com/terraform/1.5.6/terraform_1.5.6_SHA256SUMS.sig

Downloading https://www.hashicorp.com/.well-known/pgp-key.txt

Installation of Terraform 1.5.6 successful

Автоматическое определение версий 

Команда tenv <tool_alias> detect автоматически определяет нужную версию инструмента на основе различных источников. Для Terraform приоритет следующий (для других инструментов порядок приоритета описан в документации):

  1. Переменная окружения TFENV_TERRAFORM_VERSION

  2. Файл .terraform-version

  3. Файл .tfswitchrc

  4. Поле terraform_version_constraint в файле terragrunt.hcl или root.hcl

  5. Поле terraform_version_constraint в файле terragrunt.hcl.json или root.hcl.json

  6. Переменная окружения TFENV_TERRAFORM_DEFAULT_VERSION

  7. Файл ${TENV_ROOT}/Terraform/version (создается командой tenv terraform use)

  8. latest-allowed — максимально допустимая стабильная версия, удовлетворяющая ограничениям находящимся в Terraform коде

  9. Текущая установленная версия Terraform

Если ни один из источников не содержит версии, команда $ tenv terraform install установит последнюю доступную стабильную версию Terraform.

Хотя переменные окружения можно задавать вручную, основной акцент сделан на использование файлов версий. Для каждого инструмента tenv поддерживает собственный набор таких файлов. Их можно размещать:

  • в рабочем каталоге проекта

  • в любом из родительских каталогов

  • в домашней директории пользователя

Таким образом, использование файлов с описанием версий IAC-инструментов позволяет автоматически переключаться между нужными версиями при переходе между проектами — без дополнительных команд. На текущий момент tenv поддерживает все актуальные форматы таких файлов.

Важное замечание: начиная с релиза 2.0, tenv больше не устанавливает версии автоматически при вызове утилиты. Поэтому при переходе между проектами с разными версиями необходимо либо явно выполнять tenv <tool_alias> install в нужной директории, либо установить переменную окружения TENV_AUTO_INSTALL=true.

Использование в качестве библиотеки Go

tenv требует версию Go 1.23 и выше; Пакет tenvlib доступен начиная с версии 3.2. 

Пример использования:

package main

import (
    "context"
    "fmt"
    "github.com/tofuutils/tenv/v4/config/cmdconst"
    "github.com/tofuutils/tenv/v4/versionmanager/tenvlib"
)

func main() {
    tenv, err := tenvlib.Make(tenvlib.AutoInstall, tenvlib.IgnoreEnv, tenvlib.DisableDisplay)
    if err != nil {
        fmt.Println("init failed :", err)
        return
    }

    err = tenv.DetectedCommandProxy(context.Background(), cmdconst.TofuName, "version")
    if err != nil {
        fmt.Println("proxy call failed :", err)
    }
}

Документация для использования как библиотеки доступна в репозитории проекта: https://github.com/tofuutils/tenv/blob/main/TENV_AS_LIB.md

Архитектура

tenv распространяется как набор бинарных файлов: 

  • Основной бинарник tenv

  • Бинарники управляемых инструментов (прокси):

    • terraform

    • opentofu (tofu)

    • terragrunt (tg)

    • atmos

    • terramate

Прокси-подход

В основе tenv — прокси-архитектура. Главный принцип: tenv не дублирует функциональность инструментов, а управляет их версиями и маршрутизирует вызовы.

Когда вы вызываете:

$ terraform plan

происходит следующее:

  1. Наш прокси-бинарник terraform определяет нужную версия инструмента (на основе конфигурации, .tool-versions, переменных среды и пр.).

  2. Проверяется наличие нужного бинарника Terraform — при необходимости он скачивается и устанавливается.

  3. Вызов проксируется в Terraform — будто вы запускали его напрямую.

Режимы работы

  • По умолчанию: tenv перехватывает вызов, проверяет/устанавливает бинарник и исполняет команду через него.

  • TENV_DETACHED_PROXY: в этом режиме tenv просто возвращает путь к нужному бинарнику — удобно для CI/CD или shell-скриптов, где требуется явный контроль исполнения.

Отличия от конкурентов

tenv отличается от других инструментов для управления версиями следующими особенностями:

  • Поддержка широкого набора инструментов Terraform-стека: Terraform, OpenTofu, Atmos, Terragrunt, Terramate

  • Кроссплатформенность: работает на Windows, MacOS, Linux, FreeBSD, OpenBSD, Solaris

  • Интерактивный режим: предоставляет удобный интерфейс для выбора и управления версиями в интерактивном режиме.

  • Фокус на Terraform-экосистему и интеллектуальное определение версий: tenv автоматически анализирует файлы конфигурации (например, required_version в .tf и .hcl файлах) и устанавливает соответствующую версию инструмента без необходимости ручного вмешательства

  • Проверка цифровых подписей: поддерживает верификацию с использованием cosign и PGP (через gopenpgp), обеспечивая безопасность и целостность загружаемых бинарников.

  • Использование в качестве Go-модуля: предоставляет библиотеку tenvlib, позволяя интегрировать функциональность tenv непосредственно в Go-приложения

  • Активное развитие и поддержка сообщества: регулярные обновления и активное участие сообщества делают tenv надёжным выбором для долгосрочного использования.

Фишки которые мы используем во время разработки

  • GitHub как единый центр разработки — всё происходит на GitHub: сборки, релизы, issue-трекер, обсуждения. Это упрощает онбординг и делает проект более открытым для сообщества.

  • Goreleaser - используем для автоматизации сборок и релизов. Начиная с версии 3.0, мы перешли на Pro-версию: она предоставляет больше возможностей и позволяет сократить количество дополнительных GitHub Action пайплайнов для доставки.

  • golint / staticcheck / codespell — базовый набор для автоматического контроля качества кода. Помогает ловить мелкие недочёты ещё до ревью.

  • Alpine в официальном Dockerfile — минималистично, компактно и удобно для доставки.

  • Отдельный Dockerfile для локальной разработки — чтобы не ломать прод-сборку во время локальной отладки.

  • Cloudsmith для rpm/apk/deb пакетов —  используем для дистрибьюции .rpm, .apk и .deb пакетов. Как open source проект, мы получили 50 ГБ хранилища бесплатно, что покрывает все наши нужды (ссылка на программу Cloudsmith ♥ OSS).

Интересные моменты

В версии 2.0 отключили автоустановку инструментов

Автоматическая установка бинарей (через TENV_AUTO_INSTALL) внезапно начала ломать CI у части пользователей. Особенно остро это проявилось после того, как Terragrunt стал по умолчанию использовать OpenTofu (terragrunt#3172) — многие пайплайны перестали работать корректно. Пришлось отключить фичу и пересмотреть подход к поведению по умолчанию.

В версии 4.0 наконец-то добавили поддержку alpha и beta билдов

Теперь пользователи, запрашивающие новые фичи, получили возможность опробовать их до официального релиза. Это помогло нам быстрее находить баги и собирать обратную связь.

Осознанно работаем с major-версиями

В отличие от многих CLI-инструментов, которые годами остаются на 0.x или 1.x, мы не стесняемся выпускать major-релизы. Если изменение действительно ломающее — мы честно повышаем версию. Иногда это происходит быстро (как в случае с TENV_AUTO_INSTALL), а иногда текущая major-ветка живёт долго и стабильно. Главное — соблюдать здравый смысл и не бояться цифр.

Работаем над поддержкой нестандартных окружений

В процессе разработки мы столкнулись с неожиданными багами на редких архитектурах вроде ARMv6 и в нетипичных CI-средах — например, self-hosted GitLab с кастомной настройкой раннеров. Поддержка таких кейсов потребовала дополнительных усилий. Заодно мы лучше поняли, в каких реальных условиях запускают инструмент пользователи — это ценно.

Улучшение логики выбора версий

Некоторые пользователи столкнулись с ошибками после установки "битых" версий Terragrunt, которые тянулись из GitHub API. Пришлось экстренно дорабатывать механизм выбора версий, чтобы минимизировать подобные случаи.

Отказались от спонсоров

Мы осознанно отказались от GitHub Sponsors и предложений разместить баннер "supported by <company>" за деньги. Предпочитаем держать проект независимым и не превращать его в рекламную площадку. 

Как мы продвигаем tenv

tenv — это open source проект, и нам не нужно его продавать в привычном смысле. Но мы хотим, чтобы о нём знали те, кому он действительно может пригодиться. Большая часть трафика приходит к нам органически, а вот как мы этому помогаем:

  • Пишем статьи на Habr, HackerNoon, DZone — один раз даже сделали коллаборацию с env0, что было приятно.

  • Выкладывали проект на DevHunt и ProductHunt — для охвата более широкой аудитории.

  • Интегрировались в экосистему OpenTofu: сделали выделенный канал в Slack, настроили оповещение о новых релизах и периодически участвуем в обсуждениях.

  • Рассказываем о проекте в тематических Telegram-каналах и тредах на Reddit, где сидит наша целевая аудитория — инженеры, работающие с инфраструктурой.

Текущий статус проекта

Проект активно развивается. Мы стараемся быстро реагировать на багрепорты, приоритизируем фичи, которые запрашивает сообщество, и обсуждаем всё это через GitHub Issues и Discussions — всё максимально прозрачно.

В ближайших планах — покрыть как можно больше ключевого функционала юнит- и E2E-тестами, обработать накопившиеся запросы от пользователей и переработать документацию, сделав её более понятной и структурированной.

Параллельно думаем и о смежных инициативах. Например, у нас есть идея переделать GitHub Action setup-tenv, чтобы tenv было ещё проще использовать в CI/CD пайплайнах.

Контакты

Заключение

Спасибо GitVerse за отличный повод наконец-то написать статью, которую я давно собирался опубликовать на Хабре.

Если у вас есть идеи для новых фич или вы столкнулись с багами в tenv — не стесняйтесь, пишите нам и создавайте Issues на GitHub. Мы всегда рады любому фидбеку.

Всем опенсорс!

Теги:
Хабы:
+3
Комментарии0

Публикации

Работа

DevOps инженер
30 вакансий

Ближайшие события