Работа со сценариями SaltStack

Ограничения в именах сценариев:

  • в именах sls нельзя использовать точку. Точка используется для смены директорий. Поэтому some.state.sls SaltStack расшифрует как some/state.sls и ссылка include: [some.state] не сработает. Так же не рекомендуется использовать файлы .hidefile без маскировки. Перееименуем в dot_hidefile.

Объединение нескольких однородных операций:

Пример для файлов:

Base files:
  file.managed:
    - Template: Jinja
    - names:
      - /etc/salt/minion:
        - source: salt://{{ slspath }}/files/minion.jinja
      - /etc/salt/master:
        - source: salt://{{ slspath }}/files/master.jinja
        - mode: 0640

slspath — ссылка на текущее расположение sls. Полезно: можно задать общие параметры и специфические для каждого файла.

Пример для установки программ:

Some programs:
  - pkg.installed:
    - pkgs:
      - vim
      - htop
      - dnsutils

Может использоваться как нотация pkgs так и names. Работает одинаково.

Импорт сценариев:

Вариант нотации YAML:

<client/servers/serv1.sls>
import:
  - .app
  - formula/db
  - ..client_base

При импорте можно использовать относительную и абсолютную нотацию. Точка будет обозначать текущий каталог sls, две точки — отбросит на каталог вверх, три точки на — два каталога и т.д. При указании стейта без точек — будет искать с корня file_root. При обработке на миньоне импортированные sls покажет как дополнительные стейты. Т.е. пример выше выведет:

salt serv1 state.show_states
serv1:
  - clients.servers.serv1
  - clients.servers.app
  - clients.client_base
  - formula.db

Вариант Jinja:

{% include 'spam/foobar.jinja' %}

При этом надо учитывать, что для SaltStack это будет учитываться как SLS в который импортируют. Все переменные типа slspath и sls будут возвращать ссылки на стейт в который импортировали код. При обработке сценариев покажет как один стейт.

Работа с GRAINS:

В сценариях можно использовать несколько вариантов обращения к grains:

Нотация с точкой:

{% if grains.os == "Debian" %}

Удобно читать, но надо учитывать несколько моментов:

  • этот тип grains должен существовать, иначе выпадет в ошибку
  • имя grains не должно пересекаться со служебными именами функций… get и items мы так не получим.

Нотация как с массивом:

{% if grains["kernel"] != "FreeBSD" %}

Не пересекается с зарезервированными имена, но должна существовать.

Получение через метод GET:

{% if "app" in salt['grains.get']('roles',[]) %}

Плюс метода — позволяет задать значение по-умолчанию при несуществующем grains. В данном примере — пустой массив.