В чем разница между значениями по умолчанию и переменными в роли Ansible?

151

При создании новой роли Ansible шаблон создает каталог a varsи defaultsкаталог с пустым main.ymlфайлом. При определении моей роли я могу поместить определения переменных в любое из них, и они будут доступны в моих задачах.

Какая разница между введением определений в defaultsи vars? Во что следует вникнуть defaults, а во что vars? Имеет ли смысл использовать оба для одних и тех же данных?

Я знаю, что есть различие в приоритете / приоритете между ними, но я хотел бы понять, что и куда должно идти.

Допустим, моя роль создаст список каталогов в целевой системе. Я хотел бы предоставить список каталогов по умолчанию для создания, но хотел бы позволить пользователю переопределить их при использовании роли.

Вот как это будет выглядеть:

---
- directories:
  - foo
  - bar
  - baz

Я мог бы поместить это или в defaults/main.ymlили в vars/main.yml, с точки зрения выполнения, это не будет иметь никакого значения - но куда это должно пойти?

nwinkler
источник

Ответы:

113

Документация Ansible по приоритетам переменных суммирует этот niceley:

Если несколько переменных с одним и тем же именем определены в разных местах, они выигрывают в определенном порядке:

  • дополнительные переменные (-e в командной строке) всегда побеждают
  • затем идут переменные соединения, определенные в инвентаре (ansible_ssh_user и т. д.)
  • затем следует «почти все остальное» (переключатели командной строки, переменные в игре, включенные переменные, переменные ролей и т. д.)
  • затем идут остальные переменные, определенные в инвентаре
  • затем приходят факты, обнаруженные о системе
  • затем «роли по умолчанию», которые являются наиболее «дефолтными» и теряют приоритет во всем.

Предположим, у вас есть роль «tomcat», которую вы используете для установки Tomcat на несколько хостов, но вам нужны разные версии tomcat на нескольких хостах, в других случаях он должен работать от имени разных пользователей и т. Д. defaults/main.ymlФайл может выглядеть что-то вроде этого:

tomcat_version: 7.0.56
tomcat_user: tomcat

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

Изменить: Обратите внимание, что приведенный выше список предназначен для Ansible 1.x. В Ansible 2.x список был расширен. Как всегда, Ansible Documentation предоставляет подробное описание приоритета переменных для 2.x.

Брюс П
источник
4
Спасибо, это отличная страница - это то, что я искал. Я подробно расскажу о том, что нужно вставлять, defaultsа что varsдальше.
nwinkler
42
Стоит подчеркнуть: ролевые перемены имеют высокий злой приоритет . по моему опыту, они выше, чем play vars, что действительно раздражает.
tedder42
5 лет спустя, но ... Я склонен смотреть на это так: значения по умолчанию для ролей - это вещи, которые, как я ожидаю, пользователь роли где-то переопределит в своих переменных. Ролевые переменные, OTOH, позволяют мне избежать жесткого кодирования информации в задаче, но, вероятно, будут переопределены только для тестирования и изменены сопровождающим роли. Например, начальное имя пользователя администратора будет по умолчанию, но версии зависимостей будут в переменных.
ntwrkguru
41

Ролевые переменные, определенные в, varимеют очень высокий приоритет - они могут быть перезаписаны только путем передачи их в командной строке, в конкретной задаче или в блоке. Поэтому почти все ваши переменные должны быть определены в defaults.

В статье « Приоритет переменной - где поставить свои ролевые переменные » автор приводит один пример того, что нужно добавить vars: специфичные для системы константы, которые мало меняются. Таким образом, вы можете иметь vars/debian.ymlи vars/centos.ymlс одинаковыми именами переменных, но с разными значениями и включать их условно.

chiborg
источник
4

ИМХО это непрактично и не имеет смысла , что анзибль таких мест высокого приоритета по конфигурации в Варсе из ролей . Конфигурация в vars/main.ymlи defaults/main.ymlдолжна быть низкой и, вероятно, того же приоритета.

Есть ли в реальной жизни примеры случаев, когда мы хотим такого поведения?

Есть примеры, которые мы не хотим этого.

Смысл здесь в том, что конфигурация defaults/main.ymlне может быть динамической. Конфигурация в vars/main.ymlбанке. Так, например, вы можете динамически включить конфигурацию для конкретной ОС и версии, как показано в geerlingguy.postgresql

Но поскольку приоритетность в Ansible настолько странна и непрактична, geerlingguy необходимо ввести псевдопеременные, как это можно увидеть в variables.yml

- name: Define postgresql_packages.
  set_fact:
    postgresql_packages: "{{ __postgresql_packages | list }}"
  when: postgresql_packages is not defined

Это конкретный пример из реальной жизни, демонстрирующий непрактичность приоритета.

Еще один момент, на который стоит обратить внимание: мы хотим, чтобы роли можно было настраивать. Роли могут быть внешними, управляемыми кем-то другим. Как правило, вы не хотите, чтобы конфигурация в ролях имела высокий приоритет.

onknows
источник
Это должен быть комментарий, а не ответ.
ntwrkguru
3

По сути, все, что входит в «значения по умолчанию для роли» (папка по умолчанию внутри роли), является наиболее гибким и легко перезаписывается. Все, что находится в каталоге vars роли, переопределяет предыдущие версии этой переменной в пространстве имен. Идея состоит в том, что чем более явно вы видите область действия, тем больше преимуществ у командной строки -e всегда выигрывают дополнительные переменные. Переменные хоста и / или инвентаря могут преобладать над значениями по умолчанию, но не включают явные включения, такие как каталог vars или задача include_vars. доктор

pauljolsen
источник
-4

Переменные и значения по умолчанию идут рука об руку. вот пример

-name: install package
 yum: name=xyz{{package_version}} state=present

в вашем файле по умолчанию вы будете иметь что-то вроде:

package_version: 123

То, что будет делать ANSIBLE, будет принимать значение package_versionи помещать его рядом с именем пакета, чтобы оно читалось где-то как:

-name: install package
 yum: name=xyz123 state=present

Таким образом, он будет установлен, xyz123а не xyz123.4или что-либо еще в большом хранилище XYZ.

В конце это будет делать yum install -y xyz123

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

qubsup
источник
Проголосовал, потому что это не решает вопрос. Очевидно defaults, используются, когда нет varsопределенного, но ответ не объясняет, почему вы бы определили значение как одно или другое, что и было задано ОП. Сравните с объяснением ниже.
Томас Хирш