AWX: упрощаем работу с Ansible

4804b3951bc7ba473f549a3800571653.jpg

Привет, на связи Ксения Кузьменко, DevOps-инженер департамента по организации выпуска продуктов YADRO. Наша DPS-команда предоставляет платформенные сервисы для 40+ команд и 1000+ пользователей внутри компании. Мы работаем с сотнями виртуальных машин в различных локациях. Каждый день прогоняем более 250 плейбуков, из них часть связаны между собой в сложные последовательности. Конечно, инструмент для упрощения работы с Ansible был в нашей дорожной карте еще на этапе планирования.

Почему мы выбрали AWX, какие задачи решили и приятные «плюшки» получили, я расскажу в статье. О некоторых подводных камнях — тоже. 

Нужен ли AWX в вашей команде? На этот вопрос вы ответите сами, прочитав текст под катом. Я максимально подробно описала наш опыт с Ansible AWX. Если появятся вопросы — пишите в комментариях, отвечу. 

Сложности при запуске плейбука в Ansible

Перечислю основные моменты, которые приходится учитывать при работе с Ansible:  

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

  • Актуализация компонентов проекта — важно регулярно обновлять плейбуки, inventory, роли, коллекции и файлы зависимостей, если они хранятся в Git-репозитории или другом источнике.

  • Подготовка окружения Ansible— необходимо установить актуальные версии Ansible, а также соответствующие роли и коллекции. Если используются дополнительные Python-библиотеки, их также нужно установить.

  • Использование командной строки — работа через интерфейс командной строки может быть не всегда удобной. Даже для простых плейбуков может потребоваться указание множества ключей.

ansible-playbook
--vault-password-file /home/user/vault_pass
–i ./inventories/hosts.yml
–l hosts_group
--extra-vars "app_token = f15RC3rTZqKdi6RV1W0SWsTnZ7y"
./playbooks/playbook.yml

Здесь мы:

  • используем password-file для расшифровки переменных,

  • указываем путь к файлу inventory, так как у нас их несколько,

  • ограничиваем список хостов для выполнения с помощью флага l,

  • передаем в плейбук через --extra-vars переменную, в нашем случае токен.

В общем, есть масса моментов, которые можно улучшить, чтобы сделать работу с Ansible более эффективной. 

Что мы ожидаем от системы для упрощения работы с Ansible

Описав выше сложности, выводим компактный список требований. Чтобы упростить работу с Ansible, система должна:

  • предоставлять вычислительные мощности по запросу,

  • интегрироваться с системами контроля версий,

  • автоматически обновлять Ansible-проект из репозитория,

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

  • иметь графический интерфейс или API для упрощения работы и автоматизации задач —, но лучше и то и другое. 

Почему не Jenkins, Semaphore и Rundeck

Да,  Jenkins первым приходит на ум. Но есть весомое «но». Плагин job.jenkins.job.dsl предполагает использования языка Groovy.

Система нивелирует одни сложности, но в то же время вводит новые. Наша задача — подобрать максимально удобный инструмент. Тем более, на рынке существуют готовые системы, удовлетворяющие нашим требованиям. Самые популярные:  Ansible AWX,  Semaphore и Rundeck.

R&D-отдел YADRO провел исследование и выбрал Ansible AWX как наиболее функциональное и популярное решение. Хотя все перечисленные выше системы обладают похожими возможностями, AWX выделяется тем, что:

  • предоставляет расширенные версии аналогичных функций,

  • включает в себя более широкий набор возможностей по сравнению с конкурентами.

Semaphore, хоть и второй по популярности, до сих пор не поддерживает парольные фразы (passphrase) в SSH-ключах. 

Как AWX решает основные задачи

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

Обеспечение вычислительных мощностей:  AWX можно развернуть в любой из перечисленных ниже сред:

  • Kubernetes,

  • Openshift,

  • Docker/Docker Compose.

Нам больше всего подошел Kubernetes, и, соответственно, все задачи в нашей статье выполняются в нем.

Инстанс-группы определяют, где конкретно запускается плейбук. По умолчанию на AWX создаются двеинстанс-группы: Control Plane и Default.

При запуске в этих инстанс-группах плейбук будет запускаться прямо в том же pod в namespace, где развернут AWX. Также возможна интеграция с внешними кластерами k8s/OpenShift или добавление standalone-серверов и виртуальных машин для запуска на них плейбука.

Нативная интеграция с системами контроля версий:  AWX поддерживает нативную интеграцию с системами контроля версий, такими как Git. Например, репозиторий в Bitbucket можно связать с проектом в AWX.

Обновление проектов и динамического inventory:  AWX позволяет обновлять проект из Git-репозитория перед каждым запуском плейбука. Поддерживаются динамические inventory, которые также можно обновлять автоматически. Настраивается параметр cache timeout, определяющий, как долго проект или inventory будут считаться актуальными.

Автоматическая подготовка Ansible-окружения:  при синхронизации проекта AWX автоматически устанавливает роли и коллекции, указанные в файлах требований. Эти файлы могут находиться в директориях роли, коллекции или в корне репозитория. Конкретное место размещения зависит от версии AWX.

Графический интерфейс: AWX предоставляет удобный веб-интерфейс для управления задачами

Графический интерфейс: AWX предоставляет удобный веб-интерфейс для управления задачами

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

Лог и статус выполнения плейбука

Лог и статус выполнения плейбука

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

REST API

REST API

Все действия, доступные через веб-интерфейс, дублируются через REST API. Это позволяет автоматизировать задачи и интегрировать AWX с внешними системами.

Что еще дает использование AWX c Ansible

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

Поддержка стандартных параметров Ansible

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

Список ключей и их наименования на AWX

Список ключей и их наименования на AWX

Например, параметр check, позволяющий выполнить плейбук в режиме проверки, соответствует выбору job type = check в AWX.

Запуск плейбука по расписанию

В AWX можно настроить выполнение плейбука по заранее заданному графику: однократно или с заданной периодичностью

В AWX можно настроить выполнение плейбука по заранее заданному графику: однократно или с заданной периодичностью

Плагины динамических inventory

В AWX есть встроенные плагины для динамических inventory, такие как VMware, vCenter и OpenStack. Это позволяет автоматически получать актуальные данные о хостах из внешних систем. Также есть поддержка плагинов динамических inventory, включая Netbox, которые совместимы с Ansible.

Содержимое файла inventory в плагине Netbox

Содержимое файла inventory в плагине Netbox

Job slicing

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

Визуализация разделения плейбука с помощью Job slicing в AWX

Визуализация разделения плейбука с помощью Job slicing в AWX

Первая часть плейбука выполнена успешно

Первая часть плейбука выполнена успешно

Вторая часть выполнена с ошибкой

Вторая часть выполнена с ошибкой

То есть функция Job slicling помогла нам сэкономить 50% времени, которое потребовалось бы на прогон целого плейбука

Кэширование фактов

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

49a28d932f6311497699b51456d30e42.jpg

Работа с секретами

Ansible AWX предоставляет встроенные возможности для работы с секретами. Их можно добавлять через веб-интерфейс или REST API.

Создание секрета (credential) для подключения к хосту из inventory

Создание секрета (credential) для подключения к хосту из inventory

Например, для подключения к хостам из inventory можно создать секрет типа machine, который включает: имя пользователя, приватный ключ и пароль.

7e18d25fb5edd59a06537164ba623454.jpg

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

Интеграция с HashiCorp Vault

AWX поддерживает нативную интеграцию с HashiCorp Vault, что расширяет возможности безопасного управления секретами.

d495627360a9a12f372fa902aac4a0c3.jpgСоздание учетных данных (credential), которые хранятся в HashiCorp Vault

Создание учетных данных (credential), которые хранятся в HashiCorp Vault

Секреты, созданные в Vault, могут быть использованы напрямую в AWX. Но они не хранятся в самом AWX, а запрашиваются из Vault в режиме реального времени. Для этого настраиваются исходные учетные данные (source credential), указывающие, где находится хранилище секретов.

Перезапуск на недоступных хостах и хостах с ошибкой

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

c1cd4667a789628ba1456601ae1697be.jpg

Настройка параметров при запуске плейбука

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

f84b4f6392a8112c8b80bfd6bfd29e54.jpg

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

Параметры, передаваемые через extra-vars, можно дополнительно уточнять через создание Survey.

Так выглядит окно настройки опроса (Survey), которое позволяет в очень подробной форме запрашивать extra-vars для плейбука

Так выглядит окно настройки опроса (Survey), которое позволяет в очень подробной форме запрашивать extra-vars для плейбука

Что можно настроить для параметров?

  • Question — подробное описание, которое поясняет, для чего нужен параметр.

  • Description — подсказка для Question.

  • Field type — например, текстовое, числовое, выбор из списка и другие.

  • Required — возможность указать, является ли заполнение поля обязательным.

  • Minimum/Maximum length — можно настроить ограничения, например минимальную или максимальную длину вводимого значения.

  • Default answer — позволяет заранее задавать стандартные значения, которые при необходимости можно изменить.

Пример окна опроса показывает, как параметры вводятся перед запуском плейбука

Пример окна опроса показывает, как параметры вводятся перед запуском плейбука

Среды исполнения

AWX предлагает специальную функциональность, называемую среды исполнения. Это инструмент для интеграции всех необходимых зависимостей для запуска плейбуков в один образ. Среды исполнения создаются с помощью команды Ansible Builder.

Манифест для создания образа с помощью Ansible Builder

Манифест для создания образа с помощью Ansible Builder

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

Когда использовать среды исполнения:

  • есть Python-зависимости,

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

  • нужно установить роли и коллекции в автоматическом режиме, но они расположены не в корне, директории ролей или коллекций.

Поддержка команд ad-hoc

AWX поддерживает выполнение команд ad-hoc для разовых задач. Они позволяют быстро выполнять команды с помощью модулей Ansible на заданных хостах без создания плейбука.

Выбираем нужный модуль и передаем ему аргументы

Выбираем нужный модуль и передаем ему аргументы

Результат выполнения команды ad-hoc

Результат выполнения команды ad-hoc

Поддержка Webhook и Callback

AWX позволяет автоматически запускать плейбук при получении Webhook. С его помощью можно, к примеру, автоматически запускать плейбук по пушу в репозиторий.

Система на момент публикации статьи поддерживает GitHub,  GitLab и Bitbucket.

Пример настроек Webhook для BitBucket-репозитория

Пример настроек Webhook для BitBucket-репозитория

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

Пример Callback-запроса c помощью утилиты curl:

curl -k -f -i
-H 'Content-Type:application/json'
-XPOST
-d '{"host_config_key": "cfbaae23-47f8-9a40-44493b82f06a"}'
https:///api/v2/job_templates/1/callback/

Гибкая настройка прав доступа

В AWX реализована продуманная система управления доступом. Пользователи объединяются в организации (аналоги групп) для базового разграничения прав. Организация делится на команды со своим списком пользователей, проектов, учетных данных и разрешений. Команды дают возможность внедрять схемы управления на основе ролей (RBAC) и делегировать обязанности внутри организаций.

Роли и доступы можно настраивать очень гибко — части пользователей можно выдать разрешение только на просмотр определенного плейбука либо на его выполнение.

Пользователи и команды могут получать различные роли для каждой из сущностей, которые созданы в AWX

Пользователи и команды могут получать различные роли для каждой из сущностей, которые созданы в AWX

Workflow

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

Пример простой цепочки из плейбуков

Пример простой цепочки из плейбуков

Интеграция со сторонними системами логирования

У AWX есть нативная поддержка систем агрегации логов, таких как Opensearch. Дополнительной сложной настройки не требуется. Логи плейбуков автоматически передаются в систему: достаточно указать URL Opensearch, используемый индекс-паттерн и учетные данные.

Пример информации, которая выгружается в Opensearch

Пример информации, которая выгружается в Opensearch

Уведомления в мессенджеры и электронную почту

AWX поддерживает уведомления через Slack, Mattermost, электронную почту и Webhook. С помощью Webhook можно настроить, к примеру, интеграцию с Telegram.

Мы в YADRO настроили уведомления в Telegram.

Настройки интеграции с Telegram

Настройки интеграции с Telegram

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

Пример уведомлений из AWX в Telegram

Пример уведомлений из AWX в Telegram

Кластеризация из коробки

Система поддерживает конфигурации с несколькими узлами управления. Единственное ограничение: кластеризация работает только в рамках одного кластера Kubernetes. 

Запуск плейбука c AWX и без

Сначала запустим плейбук без AWX

  1. Клонируем репозиторий с Ansible-проектом командой git clone [URL репозитория].

  2. Устанавливаем Ansible:  python3 -m pip install --user ansible.

  3. Устанавливаем необходимые Python- и Galaxy-зависимости (коллекции и роли):

    1. ansible-galaxy install -r requirements.yml,

    2. python3 -m pip install -r requirements.txt.

  4. Находим используемые секреты, например, файл пароля и токен.

  5. Запускаем плейбук.

Теперь пройдем путь запуска плейбука с AWX

Создаем учетные данные (credential) для доступа к git-репозиторию в BitBucket с типом source-control, вводим имя пользователя и токен:

ce0190346dee2b301dca55d0c835208e.jpg

Создаем учетные данные (credential) с типом machine для доступа к хостам inventory. Вводим имя пользователя и пароль либо приватный SSH-ключ:

63becca3760ebc0703437d81e23809af.jpg

Создаем проект. Он нужен, чтобы связать репозиторий в BitBucket с репозиторием в AWX. Используем ранее созданные учетные данные с типом source-control из первого пункта:

f5b15347b8ba08e535c39fe4686a6c75.jpg

Создаем inventory, верхнеуровней объект, который может объединять несколько источников inventory:

4760765e8dd79c2bf14e94dcb1da8f5e.jpg

Создаем источник inventory. Указываем, что наследуем inventory из проекта. Здесь же прописываем путь до файла inventory и проекта:

cb37b018e75eed3b2d83300f17fb3431.jpg

Создаем шаблон задания, аналог плейбука, где указываем созданные ранее inventory, проект, а также пути до плейбука и учетных данных для доступа к хостам из inventory:

3a62befda3fdc8a3e1067c2296d8518e.jpg

Запускаем плейбук с AWX:

3e246905388e336a5d2d0b318cf51d1f.jpg

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

Задачи, которые нам помог решить AWX и его особенности

Сейчас в нашем департаменте AWX используют шесть команд. 

Удобная командная работа с Ansible — это самое полезное, что дал нам AWX. Нужно один раз залить конфигурацию, которую потом любой из коллег может запустить в один клик.

Реализация механизма системы управления конфигурациями. AWX сам по себе не является такой системой. Но благодаря Callback, Webhook и запуску по расписанию AWX становится полноценной системой управления конфигурацией.

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

Использование Webhook и Callback для первичной настройки серверов

Команды также активно пользуются:

  • плагинами динамического inventory, которые получают список хостов из VMware, Netbox, OpenStack,  

  • интеграцией секретов с HashiCorp Vault, которая позволяет им получать все свои секреты напрямую из Vault и хранить их в одном месте,  

  • интеграцией с Telegram, Mattermost, электронной почтой для получения уведомлений.

Особенности AWX

AWX — это неидеальный инструмент, отметим следующие особенности и минусы:

  • Нестабильная работа AWX-оператора в связке с Rancher ниже v2.0.0, а также других операторов на базе Operator SDK. Не минус, но неожиданная зависимость, которая не описана в документации. 

  • Нет грамотного логирования ошибок, если произошел сбой при выполнении Jobs. 

Что мы хотим сделать с AWX в будущем

Если конфигурация AWX объемная, то приходится много и долго кликать по графическому интерфейсу. Это не очень удобно. Мы планируем выпустить IaC, чтобы любую конфигурацию, которую можно руками сделать в AWX, можно было сделать через IaC. Бета-версия для администрирования уже есть.

Развертывание AWX через IaC мы уже реализовали.

Скоро мы попробуем использовать Callback«и для работы с плагином Foreman. Он позволяет импортировать список хостов через Ansible вместе с фактами об этих хостах и отчетами о запуске на них плейбуков. Плагин поддерживает Callback«и. Нам он нужен, чтобы после первичной настройки серверов плагин запрашивал данные для их дальнейшей настройки.

Вывод

Кроме удовлетворения основных потребностей, система предлагает целый ворох полезных дополнительных возможностей и функций. Их использование зависит от целей команды: именно для вас динамический inventory и Webhook могут оказаться бесполезными, но зато порадуют схемы управления на основе ролей (RBAC) и цепочки из плейбуков (Workflow). 

Подытожим, что еще классного мы получаем с установкой AWX для Ansible:

  • Dynamic inventory — встроенные плагины динамических inventory.

  • Secrets — встроенное хранилище секретов и интеграция с системами хранения секретов.

  • Интеграция с системами хранения и агрегации логов (например, Opensearch).

  • Кластеризация из коробки — поддержка multi-node развертывания в k8s.

  • Поддержка уведомлений — интеграция c Mattermost, Telegram, электронной почтой.

  • Поддержка Webhook.

  • Job slicing — разделение плейбука на части.

  • Workflow — возможность создания связной цепочки из плейбуков.

  • RBAC — схемы управления на основе ролей.

  • Поддержка команд Ansible ad-hoc.

  • Scheduling — запуск плейбуков по расписанию.

  • Fact cashing — кэширование фактов о хостах.

  • Execution environments — поддержка сред исполнения.

  • Callback — запуск плейбука на одном хосте.

  • Survey, Prompt on launch — запросы параметров при запуске плейбука. 

Нужен ли AWX именно вам — зависит от сложности и периодичности задач, которые вы решаете или планируете решать с помощью Ansible. Наши команды, которые используют AWX, отмечают, что работать стало проще. Они получили интуитивно понятный графический интерфейс и REST API, который позволяет использовать Ansible более удобно и контролируемо в больших распределенных командах. В качестве бонуса AWX дает ряд полезных возможностей. 

Полезные ссылки

Если остались вопросы — пишите в комментариях, я отвечу. 

© Habrahabr.ru