Какая разница между значениями по умолчанию и варами в роли Ansible?
При создании новой роли Ansible шаблон создает каталог vars
и defaults
с пустым main.yml
файлом. При определении моей роли я могу разместить определения переменных в любом из них, и они будут доступны в моих задачах.
В чем разница между помещением определений в defaults
и vars
? Что должно войти в defaults
, и что должно быть в vars
? Имеет ли смысл использовать оба для одних и тех же данных?
Я знаю, что есть разница в приоритете/приоритете между ними, но я хотел бы понять, что должно идти туда.
Скажем, что моя роль создаст список каталогов в целевой системе. Я хотел бы предоставить список каталогов по умолчанию, которые нужно создать, но хотел бы, чтобы пользователь мог переопределить их при использовании роли.
Вот что это будет выглядеть:
---
- directories:
- foo
- bar
- baz
Я мог бы разместить это либо в defaults/main.yml
, либо в vars/main.yml
, с точки зрения выполнения, это не имело бы никакого значения - но куда оно должно идти?
Ответы
Ответ 1
Документация Ansible по приоритету переменной описывает это:
Если несколько переменных с одним и тем же именем определены в разных местах, они выигрывают в определенном порядке:
- дополнительные vars (-e в командной строке) всегда выигрывают
- затем появляются переменные соединения, определенные в инвентаре (ansible_ssh_user и т.д.).
- затем приходит "большинство всего остального" (ключи командной строки, vars в игре, включены vars, vars и т.д.)
- затем выходят остальные переменные, определенные в инвентаре
- затем появляются факты, обнаруженные о системе
- затем "role defaults", которые являются самыми "невыполненными" и теряют приоритет ко всему.
Итак, предположим, что у вас есть роль "tomcat", которую вы используете для установки Tomcat на кучу веб-хостов, но вам нужны разные версии tomcat на пару хостов, нужно, чтобы они запускались как разные пользователи в других случаях и т.д. Файл defaults/main.yml
может выглядеть примерно так:
tomcat_version: 7.0.56
tomcat_user: tomcat
Поскольку это только значения по умолчанию, это означает, что они будут использоваться, если эти переменные не определены нигде для данного узла. Вы можете переопределить их через экстра-вары, через факты в вашем файле инвентаря и т.д., Чтобы указать разные значения для этих переменных.
Изменить: Обратите внимание, что приведенный выше список предназначен для Ansible 1.x. В Ansible 2.x список был расширен. Как всегда, Ansible Documentation содержит подробное описание приоритета переменной для 2.x.
Ответ 2
Ролевые переменные, определенные в var
, имеют очень высокий приоритет - их можно только перезаписать, передав их в командной строке, в конкретной задаче или в блоке. Поэтому почти все ваши переменные должны быть определены в defaults
.
В статье "" Переменный приоритет - где поставить свои ролевые валы "" автор дает один пример того, что положить в vars
: Системные константы, которые не сильно меняются. Таким образом, вы можете иметь vars/debian.yml
и vars/centos.yml
с теми же именами переменных, но с разными значениями и включать их условно.
Ответ 3
ИМХО нецелесообразно и нецелесообразно, чтобы Ansible уделял столь высокий приоритет конфигурации в vars ролях roles. Конфигурация в 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
Это конкретный пример из реальной жизни, демонстрирующий непрактичность приоритета.
Еще один момент, на который следует обратить внимание: мы хотим, чтобы роли можно было настраивать. Роли могут быть внешними, управляемыми кем-то другим. Как правило, вы не хотите, чтобы конфигурация в ролях имела высокий приоритет.
Ответ 4
Переменные и значения по умолчанию идут рука об руку. здесь пример
-name: install package
yum: name=xyz{{package_version}} state=present
в вашем файле по умолчанию у вас будет что-то вроде:
package_version: 123
Что бы вы сделали, это будет стоить package_version
и поместить его рядом с именем пакета, чтобы он читал где-то как:
-name: install package
yum: name=xyz123 state=present
Таким образом, он установит xyz123
, а не xyz123.4
или что-то еще в большом хранилище xyz.
В конце он выполнит yum install -y xyz123
Таким образом, в основном значения по умолчанию представляют собой значения, если вы не устанавливаете определенное значение для переменных, потому что это пространство не может оставаться пустым.