Spec-Zone.ru › Ansible 2.10

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

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, который представляет собой список всех ответов от модуля. Более подробный пример работы с этим можно найти в разделе Циклы по использованию register в цикле.

Примечание

Если задача завершается неудачно или пропускается, 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

Значения, переданные с использованием синтаксиса 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. Переменные группы group_vars/all из файла инвентаризации 3
  5. Переменные группы group_vars/all из playbook 3
  6. Переменные группы group_vars/* из файла инвентаризации 3
  7. Переменные группы group_vars/* из playbook 3
  8. Переменные хоста из файла инвентаризации или скрипта 2
  9. Переменные хоста host_vars/* из файла инвентаризации 3
  10. Переменные хоста host_vars/* из playbook 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 отдаёт приоритет переменным, которые были определены позже, активнее и с более явным объёмом. Переменные в папке по умолчанию внутри роли легко переопределяются. Любые переменные в папке vars роли переопределяют предыдущие версии этой переменной в пространстве имён. Переменные хоста и/или инвентаризации переопределяют значения по умолчанию роли, но явные включения, такие как папка vars или задача include_vars, переопределяют переменные инвентаризации.

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

Примечания

1

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

2(1,2)

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

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

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

4

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

Примечание

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

Примечание

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

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

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

  • Глобальный: он задаётся конфигурацией, переменными окружения и командной строкой
  • Проигрыватель: каждый проигрыватель и вложенные структуры, записи vars (vars; vars_files; vars_prompt), значения по умолчанию роли и vars.
  • Хост: переменные, напрямую связанные с хостом, такие как инвентаризация, 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

Устанавливайте значения по умолчанию в ролях, чтобы избежать ошибок неопределённой переменной. Если вы делитесь своими ролями, другие пользователи могут полагаться на разумные значения по умолчанию, которые вы добавили в файл 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

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

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 и использовать их в других ролях и в других частях вашего playbook:

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, см. в Расширенный синтаксис.

См. также

Введение в playbooks

Введение в playbooks

Условные операторы

Условные операторы в playbooks

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

Фильтры Jinja2 и их применение

Циклы

Циклы в playbooks

Роли

Организация playbook с помощью ролей

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

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

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

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

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

У вас есть вопрос? Загляните в группу Google!

irc.freenode.net

Канал IRC-чата #ansible

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

Spec-Zone.ru

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