Ansible: условно определить переменные в файле vars, если выполняется определенное условие
В зависимости от значения (True/False) переменной, определенной в group_vars, я пытаюсь определить некоторые переменные в файле vars. Их значение зависит от значения группы var.
Мой текущий файл var выглядит так:
{% if my_group_var %}
test:
var1: value
var2: value
...
varn: value
{% else %}
test:
var1: other_value
var2: other_value
...
varn: other_value
{% endif %}
Для каждой из моих ролей я использую переменную, определенную в этом файле.
Моя тестовая книга выглядит следующим образом:
- name: blabla
hosts: blabla
vars_files:
- <path>/test_vars.yml
roles: blabla
Ошибка, которую я получаю после запуска playbook:
{% if my_group_var %}
^ here
exception type: <class 'yaml.scanner.ScannerError'>
exception: while scanning for the next token
found character that cannot start any token
in "<unicode string>"
Я делаю что-то глупое здесь или это даже не поддерживается? Я пытался найти другой способ определения этих переменных (у меня их много), но мне не удалось получить что-то функциональное здесь. Какие-либо предложения?
8 ответов
В итоге я создал 2 отдельных файла var - давайте назовем их type_a.yml
а также type_b.yml
- и я определил переменную группы, которая указывает, какой файл использовать - что-то вроде type_of_file: a
, Вот так выглядит моя книга игр:
- name: blabla
hosts: blabla
vars_files:
- <path>/type_{{ type_of_file }}.yml
roles: blabla
Спасибо за ответы на все вопросы. Я считаю их действительно полезными.
Ansible позволяет одной из следующих форм определять переменную условно:
test:
var1: "{% if my_group_var %}value{% else %}other_value{% endif %}"
var2: "{{'value' if (my_group_var) else 'other_value'}}"
Комбинируя приведенный выше синтаксис с поиском vars, мы можем загрузить сложные vars (список в этом случае):
test_value_when_my_group_var_is_true:
var1: value
var2: value
test_value_when_my_group_var_is_false:
var1: other_value
var2: other_value
test: "{{ lookup('vars','test_value_when_my_group_var_is_true') if (my_group_var) else lookup('vars','test_value_when_my_group_var_is_false')}}"
Есть другой способ сделать условную загрузку дерева с помощью поиска vars. Этот способ удобен, когда вам нужно реализовать логику регистра (то есть переменная условия имеет более двух возможных значений):
test_value_when_my_group_var_is_foo:
var1: value
var2: value
test_value_when_my_group_var_is_bar:
var1: other_value
var2: other_value
test_value_when_my_group_var_is_baz:
var1: yet_another_value
var2: yet_another_value
test: "{{ lookup('vars','test_value_when_my_group_var_is_' + my_group_var) }}"
Я не думаю, что вы можете, я обычно создаю отдельные файлы для хранения коллекций условных переменных и использую when
оговорка о включении их на конкретное условие:
- include_vars: test_environment_vars.yml
when: global_platform == "test"
- include_vars: staging_environment_vars.yml
when: global_platform == "staging"
- include_vars: prod_environment_vars.yml
when:
- global_platform != "test"
- global_platform != "staging"
Почему об этом никто не упоминает?
_dist: "{{ ansible_lsb.id|lower if ansible_lsb.id == 'Raspbian' else ansible_distribution|lower }}"
Несмотря на то, что это было бы хорошо, я боюсь, что ваш путь невозможен (или я не знаю правильный путь).
Я бы предложил сначала подготовить файл vars из шаблона jinja, а затем включить его с помощью include_vars. Смотрите пример playbook:
---
- name: -Test-
hosts: local
vars:
my_group_var: False
# my_group_var: True
tasks:
- name: Prepare vars file from template.
template: src=/tmp/vars.yaml.j2
dest=/tmp/vars.yaml
- name: Include vars
include_vars: "/tmp/vars.yaml"
Содержимое примера шаблона jinja /tmp/vars.yaml.j2:
{% if my_group_var %}
test:
var1: value
var2: value
{% else %}
test:
var1: other_value
var2: other_value
{% endif %}
AFAIK, это {}, что вы пытаетесь для шаблонов Jinja2, а не для файлов YML. Из документации:
ansible допускает циклы Jinja2 и условные выражения в шаблонах, но в книгах воспроизведения мы их не используем.
Вы можете подготовить отдельный файл.yml для игры, в которой задаются переменные, которые вам нужны при использовании предложений when, и затем импортировать (или включать) их в основную книгу. Таким образом, вы можете условно определить все переменные в одном файле.
ИЛИ: используйте роли. Я думаю, что роли являются наиболее адекватным подходом для решения вашей проблемы.
Код Jinja2 ожидается в файлах.j2 для шаблонов и встроенных playbooks, где применяются некоторые правила. Вот почему вы получаете эти синтаксические ошибки.
В Ansible есть множество способов решения одних и тех же задач.
Если вы хотите определить переменные для каждой роли, один из подходов заключается в использовании отдельного файла var для каждой роли:
roles/
some_role/ # this hierarchy represents a "role"
vars/ #
main.yml # <-- variables associated with this role
defaults/ #
main.yml # <-- default lower priority variables for this role
Вышеупомянутый метод не требует условных выражений (предложение "когда").
Если вы действительно хотите иметь один-единственный файл со всеми определениями переменных, вы получите файл шаблона для генерации окончательного файла var, а затем включите / импортируйте его в свою книгу.
Я настоятельно рекомендую понять концепции повторного использования кода и динамического и статического контента.
Кроме того, если нет конфликтов пространств имен или не слишком много переменных, следует рассмотреть один единственный статический глобальный файл var для каждой книги воспроизведения или набора книг воспроизведения.
Что касается документации Ansible по использованию переменных (приоритет переменных: где я должен поместить переменную?):
Многие могут спросить, как переменные перекрывают другие. В конечном счете, философия Ansible состоит в том, что вам лучше знать, куда поместить переменную, и тогда вам нужно гораздо меньше думать об этом.
Избегайте определения переменной "x" в 47 местах и затем задавайте вопрос "какой x используется". Почему? Потому что это не дзен-философия Ansible.
Есть только один Эмпайр-стейт-билдинг. Одна Мона Лиза и т. Д. Выясните, где определить переменную, и не усложняйте это.
Там отличный упорядоченный список переменных старшинства здесь.
Я надеюсь, что следующий фрагмент (взятый из Ansible Documentation) может стать полезным дополнением к полезным вкладам других выше.
- name: Show value of 'variablename'
debug: msg="{{ lookup('vars', 'variabl' + myvar)}}"
vars:
variablename: hello
myvar: ename