Паттерн map.jinja

Тема дорожной карты · SaltStack

Паттерн map.jinja из мира Salt-формул собирает всю OS-специфическую информацию и значения по умолчанию в один файл-словарь. Это позволяет SLS-файлам формулы оставаться чистыми и избавляет их от ветвления по операционной системе. Вместо множества if-ветвлений для разных дистрибутивов, формула строит словарь соответствий по grains['os_family'], который затем дополняется переопределениями из pillar. В SLS-файлах используются готовые значения из словаря, например {{ apache.pkg }}, {{ apache.service }}, {{ apache.config }}. Этот паттерн является частью официальных конвенций формул и широко применяется в публичных формулах из GitHub-организации saltstack-formulas.

Как это работает

Классический map.jinja в корне формулы выглядит так:

{% import_yaml 'apache/defaults.yaml' as defaults %}

{% set apache = salt['grains.filter_by'](
    defaults,
    grain='os_family',
    merge=salt['pillar.get']('apache:lookup', {})
) %}

defaults.yaml содержит словарь, где ключи — значения grain: pkg: apache2 для Debian, pkg: httpd для RedHat. Функция grains.filter_by выбирает соответствующую ветку по os_family миньона, а аргумент merge накладывает сверху словарь из pillar, что позволяет администратору конкретного окружения переопределять любые значения без изменения формулы. SLS-файл импортирует результат:

{% from 'apache/map.jinja' import apache with context %}

apache_pkg:
  pkg.installed:
    - name: {{ apache.pkg }}

with context обязателен, чтобы импортируемый шаблон видел grains и pillar миньона. Без этого filter_by не сработает как ожидалось. Проверить итоговый словарь можно командой salt-call slsutil.renderer salt://apache/map.jinja, которая покажет результат после выбора ветки и merge.

Когда применять

map.jinja обязателен для любых переиспользуемых формул, которые работают с несколькими дистрибутивами, окружениями и руками. Трёхслойная модель — дефолты формулы, ветка по ОС, переопределения из pillar — покрывает почти все случаи кастомизации без правки кода формулы. Даже если у вас только Debian, вынос всех «магических значений» (пути, версии, имена сервисов) в map.jinja упрощает будущие миграции. Не нужен паттерн там, где формула состоит из одного SLS с двумя состояниями и без вариативности — словарь ради словаря только удлиняет код. Ключ pillar для переопределений принято называть <formula>:lookup.

Типичные ошибки

Самая коварная ошибка — забытый with context при импорте: шаблон рендерится, но grains внутри map.jinja пусты, filter_by уходит в ветку по умолчанию, и на RedHat-миньоне внезапно ставится apache2. Вторая ошибка — ветвление по os вместо os_family: словарь пухнет отдельными записями под Ubuntu, Debian, Mint, хотя всем нужно одно и то же. Третья ошибка — данные окружения, зашитые в defaults.yaml формулы: пароли, адреса и размеры кластера должны приходить из pillar через merge, иначе формулу нельзя ни публиковать, ни переносить. Четвёртая ошибка — расхождение структуры между defaults.yaml и pillar-переопределениями: merge объединяет словари по ключам, и опечатка в имени ключа не даст ошибку, а просто не переопределит значение.

Связанные понятия

Полезные ресурсы

🔤 Английские термины в этой теме

Слова из этой темы, которые русскоязычные часто произносят неверно. Кнопка 🔊 произносит голосом браузера.

Весь словарь терминов →