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

Статья будет полезна тем, кто изучает Ansible.

Основы Ansible Inventory

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

По умолчанию inventory хранится в /etc/ansible/hosts, но вы можете указать другое расположение с помощью флага -i или конфигурационного файла ansible.cfg.

Давайте посмотрим, как выглядит простой inventory. Наиболее распространенные форматы — INI или YAML.

[webservers]
host01.mycompany.com
host02.mycompany.com

[databases]
host03.mycompany.com
host04.mycompany.com

В этом примере мы используем формат INI, определяем четыре управляемых хоста и группируем их в две группы хостов; webservers и databases. Имена групп можно указать в скобках, как показано выше.

Inventory groups — это один из самых удобных способов управления выполнением Ansible. Хосты также могут быть частью нескольких групп.

[webservers]
host01.mycompany.com 
host02.mycompany.com

[databases]
host03.mycompany.com
host04.mycompany.com

[europe]
host01.mycompany.com
host03.mycompany.com

[asia]
host02.mycompany.com
host04.mycompany.com

Примечание: По умолчанию мы также можем ссылаться на две группы, не определяя их. Группа all включает все наши хосты в inventory, а группа ungrouped включает любой хост, который не входит ни в одну из определённых пользователем групп.

При необходимости мы также можем создавать вложенные группы хостов.

[paris]
host01.mycompany.com
host02.mycompany.com

[amsterdam]
host03.mycompany.com
host04.mycompany.com

[europe:children]
paris
amsterdam

Чтобы перечислить ряд хостов с похожими паттернами, можно воспользоваться функцией диапазона, а не определять их по одному. Например, чтобы определить десять хостов (host01, host02, .... host10):

databases
hosts[01:10].mycompany.com

Ещё одна полезная функция — это возможность определять псевдонимы для хостов в inventory. Например, мы можем использовать host01, если определим его в inventory следующим образом:

host01 ansible_host=host01.mycompany.com

Типичный шаблон настройки inventory — разделение файлов inventory для каждой среды. Ниже приведён пример хранения отдельных staging и production inventory.

staging_inventory

[webservers]
host01.staging.mycompany.com
host02.staging.mycompany.com

production_inventory

[webservers]
host01.production.mycompany.com
host02.production.mycompany.com

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

Inventory и переменные

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

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

[webservers]
host01.mycompany.com app_version=1.0.1
host02.mycompany.com app_version=1.0.2

[databases]
host03.mycompany.com app_version=1.0.3
host04.mycompany.com app_version=1.0.4

Переменные, специфичные для Ansible, такие как ansible_user или ansible_host, являются примерами переменных хоста, определённых в inventory. Дополнительные параметры см. в разделе Connecting to hosts: behavioral inventory parameters в документации.

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

[webservers]
host01.mycompany.com 
host02.mycompany.com

[databases]
host03.mycompany.com
host04.mycompany.com

[webservers:vars]
app_version=1.0.1

[databases:vars]
app_version=1.0.2

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

В том же каталоге, где мы храним наш файл inventory, мы можем создать две папки с именами group_vars и host_vars, содержащие наши файлы переменных. Например, у нас может быть файл group_vars/webservers, который содержит все переменные для веб-серверов:

group_vars/webservers

http_post: 80
ansible_user: automation_user

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

Как уже упоминалось, есть несколько способов установки переменных в Ansible, поэтому ознакомьтесь с официальной документацией Understanding variable precedence (понимание приоритета переменных) и How variables are merged (как объединяются переменные), если вы планируете использовать разные уровни для своих переменных.

Несколько источников Ansible Inventory

У нас есть возможность комбинировать различные inventory и источники, такие как каталоги, динамические inventory скрипты или плагины inventory во время выполнения или в конфигурации.

Это становится особенно полезным в случаях, когда мы хотим нацелиться на несколько сред или иным образом изолированных конфигураций. Например, чтобы одновременно обращаться к хостам development, testing, staging и production:

ansible-playbook apply_updates.yml -i development -i testing -i staging -i production

Мы можем объединить несколько источников inventory в каталог и затем управлять ими как единым целым. Такой подход удобен при управлении статическими и динамическими хостами.

inventory/
  static-inventory-1
  static-inventory-2
  dynamic-inventory-1
  dynamic-inventory-1

Затем мы можем запускать плейбуки на всех хостах в этих inventory следующим образом:

ansible-playbook apply_updates.yml -i inventory

Динамические inventory в Ansible

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

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

Чтобы увидеть список доступных плагинов inventory, которые можно использовать для создания динамических inventory, выполните команду ansible-doc -t inventory -l. Мы рассмотрим один из них — amazon.aws.aws_ec2, чтобы получать хосты из Amazon Web Services EC2.

Для получения документации и примеров по конкретному плагину используйте команду ansible-doc -t inventory amazon.aws.aws_ec2. Чтобы работать с плагином, установите коллекцию Ansible Galaxy amazon.aws, выполнив команду ansible-galaxy collection install amazon.aws.

В этом примере мы создали четыре экземпляра ec2 в AWS и хотим создать файл inventory динамически с помощью плагина.

Мы добавили два тега, environment и role, на эти экземпляры ec2, которые позже будем использовать для создания групп inventory.

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

dynamic_inventory_aws_ec2.yml

plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
  - us-east-2
  - us-west-2
 
hostnames: tag:Name
keyed_groups:
  - key: placement.region
    prefix: aws_region
  - key: tags['environment']
    prefix: env
  - key: tags['role']
    prefix: role
groups:
   # add hosts to the "private_only" group if the host doesn't have a public IP associated to it
  private_only: "public_ip_address is not defined"
compose:
  # use a private address where a public one isn't assigned
  ansible_host: public_ip_address|default(private_ip_address)

Мы объявляем плагин, который хотим использовать, и другие параметры, включая регионы, из которых следует получать данные, настройку имён хостов из тега Name и создание групп inventory на основе региона, среды и роли.

Давайте посмотрим сгенерированный inventory с помощью команды:

ansible-inventory -i dynamic_inventory_aws_ec2.yml --graph

Плагин получает информацию из нашего аккаунта AWS и создаёт несколько групп в соответствии с нашей конфигурацией и параметрами.

Чтобы сохранить inventory в файл, вы можете использовать эту команду:

ansible-inventory -i dynamic_inventory_aws_ec2.yml --list --output inventory/dynamic_inventory_aws_ec2 -y

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

Заключение

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


Если вы изучаете Ansible, приходите на курс Ansible: Infrastructure as CodeВы сможете систематизировать знания и получить практику на наших стендах.

Новый поток стартует 17 февраля 2023 года. Посмотреть программу и записаться на курс можно на нашем сайте. Ждём на курсе!

Комментарии (1)


  1. 13werwolf13
    16.01.2024 18:39
    +2

    в первой части статьи инвентарь в формате ini (давненько такого не видел) а во второй уже yaml..

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