Использование переменных
Ansible использует переменные для управления различиями между системами. С помощью Ansible вы можете выполнять задачи и плейбуки на нескольких различных системах с помощью одной команды. Для представления различий между этими системами вы можете создавать переменные с использованием стандартного синтаксиса YAML, включая списки и словари. Вы можете определять эти переменные в своих плейбуках, в вашем инвентаре, в многократно используемых файлах или ролях, или в командной строке. Вы также можете создавать переменные во время выполнения плейбука, регистрируя возвращаемое значение или значения задачи в качестве новой переменной.
После создания переменных, будь то определение их в файле, передача их в командной строке или регистрация возвращаемого значения или значений задачи в качестве новой переменной, вы можете использовать эти переменные в аргументах модулей, в условных операторах «when», в шаблонах и в циклах.
После понимания концепций и примеров на этой странице, ознакомьтесь с фактами Ansible, которые являются переменными, получаемыми с удаленных систем.
Создание допустимых имен переменных
Не все строки являются допустимыми именами переменных Ansible. Имя переменной может содержать только буквы, цифры и символы подчеркивания. Ключевые слова Python или ключевые слова playbook не являются допустимыми именами переменных. Имя переменной не может начинаться с цифры.
Имена переменных могут начинаться с символа подчеркивания. Во многих языках программирования переменные, начинающиеся с символа подчеркивания, являются приватными. Это не относится к Ansible. Переменные, начинающиеся с символа подчеркивания, обрабатываются точно так же, как и любые другие переменные. Не полагайтесь на эту конвенцию для обеспечения конфиденциальности или безопасности.
В этой таблице приведены примеры допустимых и недопустимых имен переменных:
Допустимые имена переменных | Недопустимые |
|---|---|
|
|
| ключевые слова playbook, такие как |
|
|
|
|
Простые переменные
Простые переменные объединяют имя переменной и единственное значение. Вы можете использовать этот синтаксис (и синтаксис для списков и словарей, показанных ниже) в различных местах. Для получения подробной информации о настройке переменных в инвентаре, в плейбуках, в повторно используемых файлах, в ролях или в командной строке, см. Где задать переменные.
Определение простых переменных
Вы можете определить простую переменную, используя стандартный синтаксис 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"
Булевы переменные
Ansible принимает широкий диапазон значений для булевых переменных: true/false, 1/0, yes/no, True/False и так далее. Сопоставление допустимых строк нечувствительно к регистру. Хотя примеры в документации сосредоточены на true/false для совместимости с ansible-lint настройками по умолчанию, вы можете использовать любое из следующих значений:
Допустимые значения | Описание |
|---|---|
| Истинностные значения |
| Ложные значения |
Переменные-списки
Переменная-список объединяет имя переменной с несколькими значениями. Эти значения могут храниться как маркированный список или в квадратных скобках [], разделенные запятыми.
Определение переменных как списков
Вы можете определять переменные с несколькими значениями, используя списки YAML. Например:
region: - northeast - southeast - midwest
Обращение к переменным-спискам
Когда вы используете переменные, определенные как списки (также называемые массивами), вы можете использовать отдельные, конкретные элементы из этого списка. Первый элемент в списке — элемент 0, второй — элемент 1. Например:
region: "{{ region[0] }}"
Значение этого выражения будет «северо-восток».
Переменные словарей
Словарь хранит данные в парах ключ-значение. Обычно словари используются для хранения связанных данных, таких как информация, содержащаяся в идентификаторе или профиле пользователя.
Определение переменных как словарей ключ:значение
Вы можете определять более сложные переменные, используя словари YAML. Словарь YAML сопоставляет ключи значениям. Например:
foo: field1: one field2: two
Обращение к переменным словаря ключ:значение
Когда вы используете переменные, определённые как словарь ключ:значение (также называемый хешем), вы можете использовать отдельные, конкретные поля из этого словаря, используя либо квадратные скобки, либо точку:
foo['field1'] foo.field1
Оба этих примера ссылаются на то же значение («один»). Квадратные скобки всегда работают. Использование точки может вызвать проблемы, поскольку некоторые ключи сталкиваются с атрибутами и методами словарей 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.
Объединение переменных
Для слияния переменных, содержащих списки или словари, можно использовать следующие подходы.
Объединение переменных-списков
Вы можете использовать модуль set_fact для объединения списков в новую merged_list переменную следующим образом:
vars:
list1:
- apple
- banana
- fig
list2:
- peach
- plum
- pear
tasks:
- name: Combine list1 and list2 into a merged_list var
ansible.builtin.set_fact:
merged_list: "{{ list1 + list2 }}"
Объединение переменных-словарей
Для слияния словарей используйте фильтр combine, например:
vars:
dict1:
name: Leeroy Jenkins
age: 25
occupation: Astronaut
dict2:
location: Galway
country: Ireland
postcode: H71 1234
tasks:
- name: Combine dict1 and dict2 into a merged_dict var
ansible.builtin.set_fact:
merged_dict: "{{ dict1 | ansible.builtin.combine(dict2) }}"
Подробнее см. ansible.builtin.combine .
Использование lookup merge_variables
Для слияния переменных, соответствующих заданным префиксам, суффиксам или регулярным выражениям, можно использовать lookup community.general.merge_variables, например:
merged_variable: "{{ lookup('community.general.merge_variables', '__my_pattern', pattern_type='suffix') }}"
Дополнительные сведения и примеры использования см. в документации lookup community.general.merge_variables.
Регистрация переменных
Вы можете создать переменные из выходных данных задачи 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, содержащий определения переменных. Предваряйте имена файлов JSON и YAML префиксом @.
ansible-playbook release.yml --extra-vars "@some_file.json" ansible-playbook release.yml --extra-vars "@some_file.yaml"
Приоритет переменных: Где следует разместить переменную?
Вы можете задать несколько переменных с одинаковым именем в разных местах. Когда вы это делаете, Ansible загружает все возможные найденные переменные, а затем выбирает переменную для применения на основе приоритета переменных. Другими словами, различные переменные будут перезаписывать друг друга в определенном порядке.
Команды и проекты, которые договорились о руководящих принципах определения переменных (где определять определенные типы переменных), обычно избегают проблем с приоритетом переменных. Мы рекомендуем определять каждую переменную в одном месте: определите, где определить переменную, и упростите задачу. Примеры см. в Рекомендации по установке переменных.
Некоторые параметры поведения, которые вы можете установить в переменных, также можно установить в конфигурации Ansible, в качестве командных параметров и с помощью ключевых слов playbook. Например, вы можете определить пользователя Ansible, используемого для подключения к удаленным устройствам, как переменную с ansible_user, в файле конфигурации с DEFAULT_REMOTE_USER, как параметр командной строки с -u, и с ключевым словом playbook remote_user. Если вы определите один и тот же параметр в переменной и другим способом, переменная переопределит другое значение. Этот подход позволяет настройкам, специфичным для хоста, переопределять более общие настройки. Примеры и более подробная информация о приоритете этих различных настроек см. в Управление поведением Ansible: правила приоритета.
Понимание приоритета переменных
Ansible применяет приоритет переменных, и вы можете его использовать. Вот порядок приоритетов от наименьшего к наибольшему (переменные, указанные последними, переопределяют все другие переменные):
- значения командной строки (например,
-u my_user, это не переменные) - значения по умолчанию для ролей (как определено в Структура каталога ролей) [1]
- переменные из файла инвентаризации или группы скриптов [2]
- переменные группы инвентаризации group_vars/all [3]
- переменные группы playbook group_vars/all [3]
- переменные группы инвентаризации group_vars/* [3]
- переменные группы playbook group_vars/* [3]
- переменные из файла инвентаризации или группы скриптов для хостов [2]
- переменные хоста инвентаризации host_vars/* [3]
- переменные хоста playbook host_vars/* [3]
- факты хоста / кэшированные set_facts [4]
- переменные плейбука
- переменные плейбука vars_prompt
- переменные плейбука vars_files
- переменные роли (как определено в Структура каталога ролей)
- переменные блока (только для задач в блоке)
- переменные задачи (только для задачи)
- include_vars
- set_facts / зарегистрированные переменные
- параметры роли (и include_role)
- параметры include
- дополнительные переменные (например,
-e "user=my_user") (всегда имеют приоритет)
В общем случае Ansible отдаёт приоритет переменным, которые были определены более поздно, активнее и с более явным областью действия. Переменные в папке defaults внутри роли легко переопределяются. Всё, что находится в каталоге vars роли, переопределяет предыдущие версии этой переменной в пространстве имён. Переменные хоста и/или инвентаризации переопределяют значения по умолчанию роли, но явные включения, такие как каталог vars или задача include_vars, переопределяют переменные инвентаризации.
Ansible объединяет разные переменные, установленные в инвентаризации, так, что более конкретные настройки переопределяют более общие. Например, ansible_ssh_user заданная как group_var, переопределяется ansible_user заданной как host_var. Подробнее о приоритете переменных, заданных в инвентаризации, см. Как объединяются переменные.
Примечания
Примечание
В любом разделе переопределение переменной var перезаписывает предыдущий экземпляр. Если у нескольких групп одинаковая переменная, последняя загруженная побеждает. Если вы дважды определяете переменную в разделе vars: пьесы, то вторая побеждает.
Примечание
Предыдущее описание относится к конфигурации по умолчанию hash_behaviour=replace, переключитесь на merge, чтобы частично перезаписать.
Ограничение переменных
Вы можете определить, где установить переменную, в зависимости от области, в которой вы хотите использовать это значение. Ansible имеет три основные области:
- Глобальная: устанавливается конфигурацией, переменными среды и командной строкой
- Пьеса: каждая пьеса и содержащиеся структуры, записи vars (vars; vars_files; vars_prompt), значения по умолчанию роли и vars.
- Хост: переменные, напрямую связанные с хостом, такие как инвентаризация, include_vars, факты или выходы зарегистрированных задач
Внутри шаблона у вас автоматически есть доступ ко всем переменным, которые находятся в области видимости для хоста, плюс любые зарегистрированные переменные, факты и магические переменные.
Рекомендации по тому, где задавать переменные
Вы должны выбрать место определения переменной, основываясь на желаемом контроле над значениями.
Задавайте переменные в инвентаре, которые связаны с географией или поведением. Поскольку группы часто являются сущностями, отображающими роли на хосты, вы можете часто задавать переменные в группе вместо определения их в роли. Помните: дочерние группы переопределяют родительские группы, а переменные хоста переопределяют переменные группы. Подробнее см. Определение переменных в инвентаре.
Задавайте общие значения по умолчанию в файле group_vars/all. Подробнее о том, как организовать переменные хоста и группы в вашем инвентаре, см. Организация переменных хоста и группы. Переменные группы обычно размещаются рядом с файлом инвентаря, но они также могут возвращаться динамическим инвентарем (см. Работа с динамическим инвентарем) или определяться в AWX или на платформе Red Hat Ansible Automation Platform через интерфейс или 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
Переменные, установленные в одной роли, доступны последующим ролям. Вы можете установить переменные в каталоге роли vars (как определено в Структура каталога роли) и использовать их в других ролях и в других частях вашего плейбука:
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, см. в разделе Расширенный синтаксис плейбуков.
См. также
- Плейбуки Ansible
Введение в плейбуки
- Условные операторы
Условные операторы в плейбуках
- Использование фильтров для обработки данных
Фильтры Jinja2 и их использование
- Циклы
Циклы в плейбуках
- Роли
Организация плейбуков по ролям
- Общие советы
Советы и рекомендации по плейбукам
- Специальные переменные
Список специальных переменных
- Связь
Есть вопросы? Нужна помощь? Хотите поделиться идеями? Посетите руководство по общению Ansible
© 2012–2018 Michael DeHaan
© 2018–2024 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html