
Для деплоя приложений в Kubernetes существует огромное количество различных инструментов. Если посмотреть на соответствующий раздел в CNCF Landscape, то можно потеряться в разнообразии. Поэтому иногда хорошо иметь в своем арсенале «серебряную пулю», которая подойдет для большинства задач. Helmwave вполне может стать именно таким инструментом.

В последнее время моим самым любимым инструментом для описания декларативных деплоев в Kubernetes был Helmfile. Три неочевидные, но полезные возможности Helmfile я рассмотрела в отдельной статье на Medium: “3 Helmfile features you don’t know”.
Фичи Helmfile, которые важно отметить:
Встроенная возможность шаблонизации.
Окружения с возможностью указать дефолтную конфигурацию.
Интеграция с HashiCorp Vault, AWS KMS и другими инструментами для работы с секретами.
Поддержка плагина helm diff.
Несмотря на то что GitOps и инструменты, которые реализуют этот подход, сейчас на пике популярности, к ним есть много вопросов с точки зрения надежности, управляемости и наблюдаемости. Поэтому я всегда слежу за новыми проектами: они могут оказаться проще в использовании или лучше справляться с решением конкретных проблем. Так я и нашла Helmwave.
Что такое Helmwave
Readme проекта на Github довольно емко и кратко описывает основную задачу проекта:
Helmwave — это docker-compose для @helm.
Helmwave — это инструмент для декларативного описания деплоя helm-чартов.
Давайте разберемся, чем он лучше или хуже конкурентов.
Особенности Helmwave
В Helmwave есть все необходимые стандартные фичи: everything-as-code, деплой в несколько окружений и возможность настройки дефолтной конфигурации.
Но есть и несколько неочевидных:
Пошаговый деплой (depends_on, allow_failure).
Отслеживание ресурсов Kubernetes в реальном времени при помощи kubedog.
Отсутствие внешних зависимостей: достаточно скачать бинарный файл helmwave и можно начинать деплой.

Пример использования Helmwave
Для примера я попробую решить стандартную задачу: настроить деплой в несколько окружений из одного репозитория с возможностью оверрайда конфигурации.
Для начала рассмотрим структуру проекта:
. ├── .github/ ├── .kube-linter/ │ └── config.yaml ├── README.md ├── charts/ │ ├── adservice │ ... │ └── shippingservice ├── envs-values/ │ ├── prod │ └── stage ├── helmwave.yml ├── helmwave.yml.tpl └── releases.yaml
В директории .github/ находится конфигурация для CI/CD, в моем случае это Github Actions.
В .kube-linter/ — файл конфигурации для линтинга манифестов.
В charts/ — helm-чарты для microservices-demo.
В envs-values/ хранятся значения для сред stage и production.
helmwave.yml — это файл, который рендерится из шаблона (helmwave.yml.tpl).
helmwave.yml.tpl — это шаблон конфигурации деплоя.
releases.yaml — файл со списком нужных helm-релизов и их конфигураций для деплоя.
helmwave.yml.tpl
В начале этого файла прописана версия Helmwave. Последняя версия — 0.19.5.
version: 0.19.5 .options: &options namespace: microservices-demo wait: true timeout: 300s create_namespace: true releases: {{- with readFile "releases.yaml" | fromYaml | get "releases" }} {{ range $v := . }} - name: {{ $v | get "name" }} chart: name: charts/{{ $v | get "name" }} tags: [{{ $v | get "name" }}] values: - envs-values/{{ requiredEnv "CI_ENVIRONMENT_NAME"}}/{{ $v | get "name" }}.yaml <<: *options {{ end }} {{- end }}
В этом файле мы можем использовать якорь с параметрами по умолчанию (.options) и указать его в разделе releases, когда это необходимо. Таким образом мы получим максимально DRY-конфиг. Обычно в этом месте задается ряд значений по умолчанию: namespace, helm options и т.д. Полный список параметров ищите в документации.
В разделе releases задается список релизов helm, которые нужно задеплоить. Этот список можно найти в файле releases.yaml. Каждому релизу нужно задать имя и чарт, из которого должен осуществляться деплой. Другие параметры опциональны.
Каждый релиз также содержит:
Переменные для нужного окружения, окружение задается переменной CI_ENVIRONMENT_NAME.
Тег с названием приложения, который можно использовать для фильтрации деплоя конкретных сервисов.
Параметры из якоря, добавляемые через
<< : *options.
releases.yaml
Структура releases.yaml не требует дополнительных пояснений:
releases: - name: adservice - name: cartservice ... - name: shippingservice
helmwave.yml
В этом файле будет находится отрендеренный шаблон helmwave.yml.tpl. Чтобы его сгенерировать, можно выполнить следующую команду:
$ CI_ENVIRONMENT_NAME=stage helmwave yml version: 0.19.5 .options: &options namespace: microservices-demo wait: true timeout: 300s create_namespace: true releases: - name: adservice chart: name: charts/adservice tags: [adservice] values: - envs-values/stage/adservice.yaml <<: *options ... - name: shippingservice chart: name: charts/shippingservice tags: [shippingservice] values: - envs-values/stage/shippingservice.yaml <<: *options
Процесс деплоя
Для реализации CI/CD я выбрала GitHub Actions, потому что они бесплатно доступны в GitHub. Более того, разработчики Helmwave сделали для них action, который помогает быстро и удобно использовать различные версии Helmwave в пайплайнах.
Процесс деплоя состоит из трех шагов: подготовка, запуск тестов и запуск деплоя в выбранном окружении.

Подготовка
На этапе подготовки устанавливаем необходимые инструменты — Helmwave и kind, который создаст Kubernetes кластер с помощью контейнеров. Далее в зависимости от значения CI_ENVIRONMENT_NAME подготавливаем план изменений с помощью helmwave.
Чтобы определить окружение, можно написать bash-скрипт или использовать возможности выбранной CI/CD платформы.
Пример для Github Actions:
- name: Set environment for branch run: | if [[ $GITHUB_REF == 'refs/heads/main' ]]; then echo "CI_ENVIRONMENT_NAME=prod" >> "$GITHUB_ENV" else echo "CI_ENVIRONMENT_NAME=stage" >> "$GITHUB_ENV" fi
Для тестирования и деплоя нам необходимо отрендерить helm-charts в готовые Kubernetes манифесты. Для этого нужно выполнить одну из следующих команд:
# если вы уже запускали helmwave yml helmwave build # сгенерировать helmwave.yml и все манифесты сразу helmwave build --yml
Эти команды создают директорию .helmwave, где содержатся необходимые манифесты и план.
Тестирование
Для тестирования я использую самые популярные инструменты:
Они похожи, но каждый имеет свои особенности реализации и тестируемые кейсы, поэтому я решила использовать все три в одном пайплайне.
На этом этапе можно использовать ту же команду, что и для генерации плана. Но если деплой выполняется во временной среде (как в моем случае), нужно задать дополнительный параметр diff-mode=local, который будет рендерить diff изменений локально, не отправляя запросы в кластер Kubernetes. Такой вариант также подходит для использования в CI.
helmwave build --yml --diff-mode=local
Чтобы развернуть приложение, выполните следующую команду:
helmwave up # если хотите увидеть ход процесса деплоя helmwave up --kubedog # или все сразу helmwave up --yml --build --kubedog
Очистка
Чтобы удалить все созданные ресурсы, нужно выполнить одну из следующих команд:
helmwave down # или удалить namespace в Kubernetes kubectl delete microservices-demo

Helmwave — это полноценная альтернатива helmfile и другим похожим инструментам. Несмотря на то что проект достаточно молодой, у него есть полезные и неочевидные функции, и я с интересом буду смотреть за его развитием.
От себя могу рекомендовать использовать его в ситуации, когда вам нужно быстро настроить деплой приложения и иметь возможность наблюдать за процессом деплоя в режиме реального времени. Также helmwave хорошо подойдет для CI и тестовых окружений из-за полноценной поддержки шаблонизации, возможности получать логи приложения при его непосредственном деплое и смотреть diff между тем, что уже есть в кластере, и планируемыми изменениями.
