Spec-Zone.ru › Ansible 2.11

Использование переменных

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

После создания переменных, либо путем определения их в файле, передачи их в командной строке, или регистрации возвращаемого значения или значений задачи как новой переменной, вы можете использовать эти переменные в аргументах модуля, в условных операторах «when», в шаблонах и в циклах. Репозиторий ansible-examples github содержит множество примеров использования переменных в Ansible.

После того, как вы освоите концепции и примеры на этой странице, ознакомьтесь с фактами Ansible, которые являются переменными, извлекаемыми с удаленных систем.

  • Создание допустимых имён переменных
  • Простые переменные

    • Определение простых переменных
    • Обращение к простым переменным
  • Когда нужно указывать переменные в кавычках (особенность YAML)
  • Переменные-списки

    • Определение переменных как списков
    • Обращение к переменным-спискам
  • Переменные-словари

    • Определение переменных как словарей (ключ:значение)
    • Обращение к переменным-словарям (ключ:значение)
  • Регистрация переменных
  • Обращение к вложенным переменным
  • Преобразование переменных с помощью фильтров Jinja2
  • Где задавать переменные

    • Определение переменных в инвентаре
    • Определение переменных в плейбуке
    • Определение переменных во включённых файлах и ролях
    • Определение переменных во время выполнения

      • Формат ключ=значение
      • Формат JSON-строки
      • Переменные из JSON или YAML файла
  • Приоритет переменных: куда поместить переменную?

    • Понимание приоритета переменных
    • Область действия переменных
    • Рекомендации по заданию переменных
  • Использование расширенного синтаксиса переменных

Создание допустимых имён переменных

Не все строки являются допустимыми именами переменных Ansible. Имя переменной может содержать только буквы, цифры и символы подчеркивания. Ключевые слова Python или ключевые слова плейбука не являются допустимыми именами переменных. Имя переменной не может начинаться с цифры.

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

В этой таблице приведены примеры допустимых и недопустимых имён переменных:

Допустимые имена переменных

Недопустимые

foo

*foo, ключевые слова Python, такие как async и lambda

foo_env

ключевые слова плейбука, такие как environment

foo_port

foo-port, foo port, foo.port

foo5, _foo

5foo, 12

Простые переменные

Простые переменные объединяют имя переменной с единственным значением. Вы можете использовать этот синтаксис (и синтаксис для списков и словарей, показанных ниже) в различных местах. Подробности о настройке переменных в инвентаре, в плейбуках, в переиспользуемых файлах, в ролях или в командной строке см. в разделе Где задавать переменные.

Определение простых переменных

Вы можете определить простую переменную, используя стандартный синтаксис YAML. Например:

remote_install_path: /opt/my_app_config

Обращение к простым переменным

После определения переменной используйте синтаксис Jinja2 для обращения к ней. Переменные Jinja2 используют двойные фигурные скобки. Например, выражение My amp goes to {{ max_amp_value }} демонстрирует самый базовый вид подстановки переменных. Вы можете использовать синтаксис Jinja2 в плейбуках. Например:

ansible.builtin.template:
  src: foo.cfg.j2
  dest: '{{ remote_install_path }}/foo.cfg'

В этом примере переменная определяет расположение файла, которое может различаться на разных системах.

Примечание

Ansible разрешает циклы и условные операторы Jinja2 в шаблонах, но не в плейбуках. Вы не можете создать цикл задач. Ansible плейбуки — это чисто машинно-разбираемый YAML.

Когда нужно указывать переменные в кавычках (особенность YAML)

Если вы начинаете значение с {{ foo }}, вы должны привести всё выражение в кавычки для создания валидного синтаксиса YAML. Если вы не приведёте всё выражение в кавычки, парсер YAML не сможет интерпретировать синтаксис — он может быть переменной или началом YAML словаря. Для руководства по написанию YAML, обратитесь к документации YAML Синтаксиса.

Если вы используете переменную без кавычек, как в этом примере:

- hosts: app_servers
  vars:
      app_path: {{ base_path }}/22

Вы увидите: ERROR! Syntax Error while loading YAML. Если вы добавите кавычки, Ansible работает корректно:

- hosts: app_servers
  vars:
       app_path: "{{ base_path }}/22"

Переменные-списки

Переменная-список объединяет имя переменной с несколькими значениями. Несколько значений могут храниться как упорядоченный список или в квадратных скобках [], разделённых запятыми.

Определение переменных как списков

Вы можете определять переменные с несколькими значениями, используя YAML списки. Например:

region:
  - northeast
  - southeast
  - midwest

Обращение к переменным-спискам

Когда вы используете переменные, определённые как список (также называемый массивом), вы можете использовать отдельные, конкретные элементы из этого списка. Первый элемент в списке — элемент 0, второй элемент — элемент 1. Например:

region: "{{ region[0] }}"

Значение этого выражения будет «северо-восток».

Переменные-словари

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

Определение переменных как словарей (ключ:значение)

Вы можете определять более сложные переменные, используя YAML словари. YAML словарь сопоставляет ключи со значениями. Например:

foo:
  field1: one
  field2: two

Обращение к переменным-словарям (ключ:значение)

Когда вы используете переменные, определённые как словарь (также называемый хеш), вы можете использовать отдельные, конкретные элементы из этого словаря, используя либо квадратную нотацию, либо точечную нотацию:

foo['field1']
foo.field1

Оба этих примера ссылаются на одно и то же значение («one»). Квадратная нотация всегда работает. Точечная нотация может создавать проблемы, потому что некоторые ключи совпадают с атрибутами и методами словарей python. Используйте квадратную нотацию, если вы используете ключи, которые начинаются и заканчиваются двумя символами подчеркивания (которые зарезервированы для специального значения в python) или являются любыми из известных общедоступных атрибутов:

add, append, as_integer_ratio, bit_length, capitalize, center, clear, conjugate, copy, count, decode, denominator, difference, difference_update, discard, encode, endswith, expandtabs, extend, find, format, fromhex, fromkeys, get, has_key, hex, imag, index, insert, intersection, intersection_update, isalnum, isalpha, isdecimal, isdigit, isdisjoint, is_integer, islower, isnumeric, isspace, issubset, issuperset, istitle, isupper, items, iteritems, iterkeys, itervalues, join, keys, ljust, lower, lstrip, numerator, partition, pop, popitem, real, remove, replace, reverse, rfind, rindex, rjust, rpartition, rsplit, rstrip, setdefault, sort, split, splitlines, startswith, strip, swapcase, symmetric_difference, symmetric_difference_update, title, translate, union, update, upper, values, viewitems, viewkeys, viewvalues, zfill

Регистрация переменных

Вы можете создать переменные из результата задания Ansible с помощью ключевого слова задания register. Вы можете использовать зарегистрированные переменные в последующих заданиях вашего плана. Например:

- hosts: web_servers

  tasks:

     - name: Run a shell command and register its output as a variable
       ansible.builtin.shell: /usr/bin/foo
       register: foo_result
       ignore_errors: true

     - name: Run a shell command using output of the previous task
       ansible.builtin.shell: /usr/bin/bar
       when: foo_result.rc == 5

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

Зарегистрированные переменные хранятся в памяти. Вы не можете кэшировать зарегистрированные переменные для использования в будущих планах. Зарегистрированные переменные действуют только на хосте для остальной части текущего выполнения плана.

Зарегистрированные переменные являются переменными уровня хоста. Когда вы регистрируете переменную в задании с циклом, зарегистрированная переменная содержит значение для каждого элемента в цикле. Структура данных, помещённая в переменную во время цикла, будет содержать атрибут results — список всех ответов модуля. Более подробный пример работы см. в разделе Циклы по использованию регистров с циклом.

Примечание

Если задание завершается ошибкой или пропускается, Ansible всё равно регистрирует переменную с статусом ошибки или пропуска, если только задание не пропущено на основе тегов. Подробнее о добавлении и использовании тегов см. в разделе Теги.

Обращение к вложенным переменным

Многие зарегистрированные переменные (и факты) являются вложенными структурами данных YAML или JSON. Вы не можете получить доступ к значениям из этих вложенных структур данных с помощью простого {{ foo }} синтаксиса. Вы должны использовать либо квадратную нотацию, либо точечную нотацию. Например, чтобы получить IP-адрес из фактов с помощью квадратной нотации:

{{ ansible_facts["eth0"]["ipv4"]["address"] }}

Чтобы получить IP-адрес из фактов с помощью точечной нотации:

{{ ansible_facts.eth0.ipv4.address }}

Преобразование переменных с помощью фильтров Jinja2

Фильтры Jinja2 позволяют преобразовывать значение переменной в выражении шаблона. Например, фильтр capitalize приводит любые передаваемые ему значения к верхнему регистру; фильтры to_yaml и to_json изменяют формат значений ваших переменных. Jinja2 содержит множество встроенных фильтров, а Ansible предоставляет ещё больше. Для получения дополнительных примеров фильтров см. Использование фильтров для обработки данных.

Где задавать переменные

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

Определение переменных в инвентаризации

Вы можете определить разные переменные для каждого хоста или задать общие переменные для группы хостов в вашей инвентаризации. Например, если все машины в группе [Boston] используют «boston.ntp.example.com» в качестве сервера NTP, вы можете задать переменную группы. На странице Как создать инвентаризацию содержатся подробности по настройке переменных хоста и переменных группы в инвентаризации.

Определение переменных в плане

Вы можете определить переменные непосредственно в плане:

- hosts: webservers
  vars:
    http_port: 80

Когда вы определяете переменные в плане, они видны любому, кто выполняет этот план. Это особенно полезно, если вы широко делитесь планами.

Определение переменных в включённых файлах и ролях

Вы можете определить переменные в переиспользуемых файлах переменных и/или в переиспользуемых ролях. Когда вы определяете переменные в переиспользуемых файлах переменных, конфиденциальные переменные отделяются от планов. Это разделение позволяет хранить ваши планы в системе управления версиями и даже делиться планами без риска раскрытия паролей или другой конфиденциальной и личной информации. Сведения о создании переиспользуемых файлов и ролей см. в разделе Переиспользование артефактов Ansible.

Этот пример показывает, как можно включить переменные, определённые во внешнем файле:

---

- hosts: all
  remote_user: root
  vars:
    favcolor: blue
  vars_files:
    - /vars/external_vars.yml

  tasks:

  - name: This is just a placeholder
    ansible.builtin.command: /bin/echo foo

Содержимое каждого файла переменных — это простой словарь YAML. Например:

---
# in the above example, this would be vars/external_vars.yml
somevar: somevalue
password: magic

Примечание

Вы можете хранить переменные на уровне хоста и группы в подобных файлах. Чтобы узнать о структурировании переменных, см. Структурирование переменных хоста и группы.

Определение переменных во время выполнения

Вы можете определять переменные во время выполнения вашего плана, передавая переменные в командной строке с помощью аргумента --extra-vars (или -e). Вы также можете запросить ввод пользователя с помощью vars_prompt (см. Интерактивный ввод: подсказки). При передаче переменных в командной строке используйте строку в одинарных кавычках, содержащую одну или несколько переменных в одном из форматов ниже.

Формат ключ=значение

Значения, передаваемые в формате key=value, интерпретируются как строки. Используйте формат JSON, если вам нужно передавать значения, отличные от строк, такие как булевы значения, целые числа, числа с плавающей запятой, списки и т. д.

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"

Формат JSON-строки

ansible-playbook release.yml --extra-vars '{"version":"1.23.45","other_variable":"foo"}'
ansible-playbook arcade.yml --extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'

При передаче переменных с --extra-vars, вы должны правильно экранировать кавычки и другие специальные символы как для вашего разметки (например, JSON), так и для вашей оболочки:

ansible-playbook arcade.yml --extra-vars "{\"name\":\"Conan O\'Brien\"}"
ansible-playbook arcade.yml --extra-vars '{"name":"Conan O'\\\''Brien"}'
ansible-playbook script.yml --extra-vars "{\"dialog\":\"He said \\\"I just can\'t get enough of those single and double-quotes"\!"\\\"\"}"

Если у вас много специальных символов, используйте файл JSON или YAML, содержащий определения переменных.

Переменные из файла JSON или YAML

ansible-playbook release.yml --extra-vars "@some_file.json"

Приоритет переменных: где разместить переменную?

Вы можете задать несколько переменных с одинаковым именем во многих разных местах. В этом случае Ansible загружает все возможные переменные, а затем выбирает переменную для применения на основе приоритета переменных. Другими словами, различные переменные будут переопределять друг друга в определённом порядке.

Команды и проекты, которые согласовывают правила для определения переменных (где определять определённые типы переменных), обычно избегают проблем с приоритетом переменных. Мы рекомендуем определить каждую переменную в одном месте: решите, где определить переменную, и сохраните простоту. Примеры см. в разделе Советы по тому, где задавать переменные.

Некоторые параметры поведения, которые можно задать в переменных, можно также задать в конфигурации Ansible, в качестве опций командной строки и с помощью ключевых слов плана. Например, вы можете определить пользователя, которого Ansible использует для подключения к удалённым устройствам, как переменную с ansible_user, в файле конфигурации с DEFAULT_REMOTE_USER, как опцию командной строки с -u, и с помощью ключевого слова плана remote_user. Если вы определяете один и тот же параметр в переменной и другим способом, переменная переопределяет другое значение. Этот подход позволяет настройкам, специфичным для хоста, переопределять более общие настройки. Примеры и более подробная информация о приоритете этих различных настроек см. в разделе Управление поведением Ansible: правила приоритета.

Понимание приоритета переменных

Ansible применяет приоритет переменных, и вы можете им воспользоваться. Вот порядок приоритета от наименьшего к наибольшему (переменные, указанные последними, переопределяют все другие переменные):

  1. Значения командной строки (например, -u my_user, это не переменные)
  2. Значения по умолчанию роли (определены в role/defaults/main.yml) 1
  3. Переменные из файла инвентаризации или группы скриптов 2
  4. Переменные группы all из файла инвентаризации 3
  5. Переменные группы all из плейбука 3
  6. Переменные группы * из файла инвентаризации 3
  7. Переменные группы * из плейбука 3
  8. Переменные хоста из файла инвентаризации или скрипта 2
  9. Переменные хоста * из файла инвентаризации 3
  10. Переменные хоста * из плейбука 3
  11. Факты хоста / кэшированные значения set_facts 4
  12. Переменные плейбука
  13. Переменные плейбука vars_prompt
  14. Переменные плейбука vars_files
  15. Переменные роли (определены в role/vars/main.yml)
  16. Переменные блока (только для задач в блоке)
  17. Переменные задачи (только для задачи)
  18. include_vars
  19. set_facts / зарегистрированные переменные
  20. Параметры роли (и include_role)
  21. Параметры include
  22. Дополнительные переменные (например, -e "user=my_user")(всегда имеют наивысший приоритет)

В общем случае Ansible отдает предпочтение переменным, которые были определены более недавно, активнее и с более явным объёмом. Переменные в папке defaults внутри роли легко переопределяются. Любые переменные в папке vars роли переопределяют предыдущие версии этой переменной в пространстве имён. Переменные хоста и/или инвентаризации переопределяют значения по умолчанию роли, но явные включения, такие как папка vars или задача include_vars, переопределяют переменные инвентаризации.

Ansible объединяет различные переменные, заданные в инвентаризации, так что более специфические настройки переопределяют более общие настройки. Например, ansible_ssh_user, заданная как group_var, переопределяется ansible_user, заданная как host_var. Подробную информацию о приоритете переменных, заданных в инвентаризации, см. в Как объединяются переменные.

Примечания

1

Задачи в каждой роли видят значения по умолчанию своей роли. Задачи, определённые вне роли, видят значения по умолчанию последней роли.

2(1,2)

Переменные, определённые в файле инвентаризации или предоставленные динамической инвентаризацией.

3(1,2,3,4,5,6)

Включает переменные, добавленные плагинами vars, а также host_vars и group_vars, которые добавляются стандартным плагином vars, поставляемым с Ansible.

4

Если созданы с кэшируемым параметром set_facts, переменные имеют высокий приоритет в плейбуке, но имеют тот же приоритет, что и факты хоста, когда они взяты из кэша.

Примечание

В любом разделе переопределение переменной перебивает предыдущее значение. Если несколько групп имеют одинаковую переменную, загружается последняя. Если вы определены переменную дважды в разделе vars: плейбука, то второе значение побеждает.

Примечание

Предыдущее описание относится к настройкам по умолчанию hash_behaviour=replace, переключитесь на merge для частичного переопределения.

Определение областей переменных

Вы можете определить, где установить переменную, в зависимости от того, какой охват должен иметь это значение. Ansible имеет три основные области:

  • Глобальная: устанавливается конфигурацией, переменными среды и командной строкой
  • Плейбук: каждый плейбук и содержащие его структуры, записи vars (vars; vars_files; vars_prompt), значения по умолчанию роли и переменные роли.
  • Хост: переменные, напрямую связанные с хостом, например, инвентаризация, include_vars, факты или результаты зарегистрированных задач

Внутри шаблона вы автоматически получаете доступ ко всем переменным, которые находятся в области действия для хоста, а также к любым зарегистрированным переменным, фактам и магическим переменным.

Рекомендации по определению переменных

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

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

Устанавливайте общие значения по умолчанию в файле group_vars/all. Подробную информацию о том, как организовать переменные хоста и группы в инвентаризации, см. в Организация переменных хоста и группы. Переменные группы обычно размещаются рядом с файлом инвентаризации, но также могут возвращаться динамической инвентаризацией (см. Работа с динамической инвентаризацией) или определяться в Red Hat Ansible Tower из интерфейса или API:

---
# file: /etc/ansible/group_vars/all
# this is the site wide default
ntp_server: default-time.example.com

Устанавливайте местоположения специфические переменные в файлах group_vars/my_location. Все группы являются дочерними группами all группы, поэтому переменные, заданные здесь, переопределяют переменные, заданные в group_vars/all.

---
# file: /etc/ansible/group_vars/boston
ntp_server: boston-time.example.com

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

---
# file: /etc/ansible/host_vars/xyz.boston.example.com
ntp_server: override.example.com

Устанавливайте значения по умолчанию в ролях, чтобы избежать ошибок undefined-variable. Если вы делитесь своими ролями, другие пользователи могут полагаться на разумные значения по умолчанию, которые вы добавили в файл roles/x/defaults/main.yml, или они могут легко переопределить эти значения в инвентаризации или в командной строке. Более подробную информацию см. в Роли. Например:

---
# file: roles/x/defaults/main.yml
# if no other value is supplied in inventory or as a parameter, this value will be used
http_port: 80

Устанавливайте переменные в ролях, чтобы гарантировать использование значения в этой роли и не переопределять переменные инвентаризации. Если вы не разделяете свою роль с другими, вы можете определить поведение, специфичное для приложения, например, порты, таким образом, в roles/x/vars/main.yml. Если вы разделяете роли с другими, размещение переменных здесь делает их труднее переопределить, хотя они все еще могут быть переопределены путем передачи параметра роли или установления переменной с помощью -e.

---
# file: roles/x/vars/main.yml
# this will absolutely be used in this role
http_port: 80

Передавайте переменные как параметры при вызове ролей для максимальной ясности, гибкости и видимости. Этот подход переопределяет любые значения по умолчанию, которые существуют для роли. Например:

roles:
   - role: apache
     vars:
        http_port: 8080

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

roles:
   - role: app_user
     vars:
        myname: Ian
   - role: app_user
     vars:
       myname: Terry
   - role: app_user
     vars:
       myname: Graham
   - role: app_user
     vars:
       myname: John

Переменные, установленные в одной роли, доступны последующим ролям. Вы можете установить переменные в файле roles/common_settings/vars/main.yml и использовать их в других ролях и в других местах плейбука:

roles:
   - role: common_settings
   - role: something
     vars:
       foo: 12
   - role: something_else

Примечание

Существуют некоторые защиты, чтобы избежать необходимости именования переменных. В этом примере переменные, определенные в ‘common_settings’, доступны для задач ‘something’ и ‘something_else’, но задачи в ‘something’ имеют foo, установленное в 12, даже если ‘common_settings’ устанавливает foo в 20.

Вместо того, чтобы беспокоиться о приоритете переменных, мы рекомендуем вам подумать о том, насколько легко или часто вы хотите переопределить переменную, когда решаете, где ее установить. Если вы не уверены, какие еще переменные определены, и вам нужно определенное значение, используйте --extra-vars (-e) для переопределения всех других переменных.

Использование расширенного синтаксиса переменных

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

См. также

Введение в плейбуки

Введение в плейбуки

Условные выражения

Условные операторы в плейбуках

Использование фильтров для обработки данных

Фильтры Jinja2 и их использование

Циклы

Циклы в плейбуках

Роли

Организация плейбуков по ролям

Советы и рекомендации

Советы и рекомендации по плейбукам

Специальные переменные

Список специальных переменных

Список рассылки пользователей

Есть вопросы? Загляните в google группу!

irc.freenode.net

IRC чат канал #ansible

© 2012–2018 Michael DeHaan
© 2018–2021 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.11/user_guide/playbooks_variables.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API