Перевели статью об основах 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 года. Посмотреть программу и записаться на курс можно на нашем сайте. Ждём на курсе!
13werwolf13
в первой части статьи инвентарь в формате ini (давненько такого не видел) а во второй уже yaml..
и про динамический инвентарь конечно интересно (лично я за ненадобностью вообще не думал что так можно), но о более приземлённых возможностях (вроде вложенных групп и дополнительных переменных) ни слова, словно прочитал не статью а начало и конец статьи пропустив середину..