Основы автоматизации в Ansible: роли и сценарии
Ansible — инструмент управления конфигурациями. Задачи, которые решаются с его помощью, часто повторяются у разных людей и команд. Как и в случае программирования, где общий код выделяют в библиотеку, Ansible выделяет повторяющиеся вещи в роли. В статье объясним, в чём основная идея ролей, а также подробно разберём процесс их создания.
Что такое роли
Роль в Ansible — набор задач или обработчик переменных, файлов и других артефактов, которые распространяются и подключаются как единое целое к плейбуку. Обычно она отвечает за высокоуровневые задачи: установку баз данных, веб-серверов и др. Но иногда может использоваться для автоматизации работы с каким-то низкоуровневым сервисом, который не встроен в Ansible.
По мере того как вы добавляете в плейбуки функциональность, они становятся всё более громоздкими и сложными в обслуживании. Здесь на помощь приходят роли — они разбивают сложные плейбуки на отдельные более мелкие фрагменты, которые могут координироваться центральной точкой входа.
Основная идея ролей заключается в том, чтобы позволить повторно использовать общие шаги настройки между различными типами серверов.
«DevOps Tools для разработчиков»
Создание роли
Чтобы Ansible смог найти и использовать роли, нужна специально разработанная структура каталогов. Создадим каталог с именем roles:
cd ~
mkdir roles
cd roles
В этом каталоге определим роли, которые можно использовать повторно в нескольких плейбуках и на разных серверах. Каждая роль, которую мы создадим, требует собственного каталога. Для примера мы возьмём сценарий Apache и превратим его в многоразовую роль Ansible:
Создадим каталог Apache для нашей роли и заполним его каталогами:
mkdir apache
cd apache
Затем с помощью команды mkdir создадим необходимый набор подкаталогов:
mkdir defaults files handlers meta templates tasks vars
Эти каталоги будут содержать весь код, который нужен для реализации роли.
В зависимости от сложности выполняемых задач роли может использовать один или несколько каталогов. Что представляют собой каталоги:
defaults: позволяет устанавливать переменные по умолчанию для включенных или зависимых ролей.
files: содержит статические файлы и файлы сценариев, которые могут быть скопированы на удалённый сервер или выполнены на нём.
handlers: все обработчики, которые ранее были в вашем плейбуке, теперь могут быть добавлены в каталог.
meta: для метаданных роли, которые используются для управления зависимостями. Например, вы можете определить список ролей, которые должны быть применены до вызова текущей роли.
templates: для шаблонов, которые генерируют файлы на удалённых хостах.
tasks: содержит один или несколько файлов с задачами, которые определяются в разделе tasks обычного плейбука Ansible. Эти задачи могут напрямую ссылаться на файлы и шаблоны, содержащиеся в соответствующих каталогах внутри роли, без необходимости указывать полный путь к файлу.
vars: переменные для роли могут быть указаны в файлах внутри каталога, а затем ссылаться на них в другом месте роли.
Превращаем плейбук в роль
Превратим плейбук Apache в роль для более эффективной организации. Поскольку структура roles/apache2/{subdirectories} уже настроена, создадим несколько YAML-файлов.
Файл задач main.yml
Начнем с подкаталога tasks. Перейдите в каталог:
cd ~/roles/apache/tasks
В нём нужно создать основной файл.yml и наполнить его содержимым плейбука Apache:
nano main.yml
Когда вы начнёте, файл будет выглядеть так:
Нам нужно сохранить только первую строку --- и выделенные строки в разделе «Задачи». Удалим посторонние пробелы слева от наших задач и добавим раздел для включения модуля Apache под названием modsecurity. После этих изменений новый файл ~/roles/apache/tasks/main.yml будет выглядеть следующим образом:
Теперь файл tasks проще понимать, потому что он содержит только фактические шаги, которые будут выполняться при использовании роли Apache.
Обратите внимание, что src=index.html и src=vhost.tpl используются для ссылок на файлы в роли без какого-либо предшествующего пути. Структура каталогов позволяет ссылаться на файлы и шаблоны непосредственно по их названию — Ansible найдёт их автоматически.
Сохраните и закройте файл, когда закончите редактирование.
Файл с обработчиками событий main.yml
Когда у нас есть основная часть плейбука в файле tasks/main.yml, нужно переместить раздел обработчиков в файл, расположенный по адресу handlers/main.yml.
Перейдите в подкаталог handlers:
cd ~/roles/apache/handlers
Откройте файл в текстовом редакторе и вставьте содержимое оригинального playbook.yml:
nano main.yml
Цветом выделены части, которые нам нужно сохранить:
Удалим лишние пробелы, чтобы файл выглядел так:
Сохраните и закройте файл, когда закончите.
Добавление файлов и шаблонов
Следующий шаг — проверка наличия файла index.html и шаблона vhost.tpl. Поскольку мы ссылаемся на них в файле tasks/main.yml, они должны существовать, иначе Ansible не сможет правильно запустить роль.
Создадим файл index.html в каталоге ~/roles/apache/files:
cd ~/roles/apache/files
nano index.html
Вставим в редактор следующие строки:
Сохраните изменения и закройте его.
Перейдём к редактированию шаблона. Для этого откройте каталог шаблонов и введите команду nano:
cd ~/roles/apache/files
nano index.html
Вставьте эти строки в редактор, затем сохраните и закройте его:
Мета каталог
В созданной роли Apache нам не нужны никакие зависимости. Однако в гипотетическом случае, если бы наша роль зависела от другой роли (apt), мы могли бы добавить в мета каталог файл main.yml. Он бы выглядел так:
Это бы гарантировало запуск роли apt перед нашей ролью Apache. Создание подобных зависимостей полезно с более сложными ролями, которые требуют наличия других частей программного обеспечения или конфигурации перед запуском фактической роли.
Каталог vars
По умолчанию каталог vars можно использовать для установки переменных. Однако применять его для небольших ролей не рекомендуется. Причина — vars позволяет деталям конфигурации находиться в иерархии ролей. Роль — это в основном общие задачи и зависимости, а переменные — это данные конфигурации. Объединение двух факторов затрудняет повторное использование роли в другом месте.
Вместо этого лучше указать детали конфигурации вне роли, чтобы вы могли легко поделиться ею, не беспокоясь о раскрытии конфиденциальной информации. Кроме того, переменные, объявленные в роли, легко переопределяются переменными в других местах.
Однако каталог vars всё же стоит упомянуть, потому что он полезен для сложных ролей. Например, если роли необходимо поддерживать различные дистрибутивы Linux, указание значений по умолчанию для переменных может быть полезно для обработки различных имен пакетов, версий и конфигураций.
Другие файлы
Когда вы создаёте роли с большим количеством задач, зависимостей или условной логики, они становятся большими и трудными для понимания. В подобных ситуациях лучше разделить задачи на их собственные файлы и включить в tasks/main.yml.
Скажем, если бы у нас был дополнительный набор задач по настройке TLS для нашего сервера Apache, мы могли бы выделить их в отдельный файл — вызвать файл tasks/tls.yml и включить его в файл tasks/main.yml:
Работа с плейбуком
Мы настроили структуру ролей и теперь можем использовать плейбуки для управления сервером без необходимости повторного создания задач.
Создадим плейбук:
cd ~
nano playbook.yml
Теперь откройте файл и вставьте эти строки:
Сначала мы перечисляем серверы, на которых хотим запустить роль — для этого используем hosts: all. Затем мы объявляем роли. В данном случае роль одна — apache. Это весь план действий — он прост, быстро читается и понимается. Поддержание такого порядка в плейбуках позволяет сосредоточиться на общих целях настройки серверов, а не на механизме выполнения отдельных задач.
Ansible Galaxy
Это статья была бы неполной без упоминания Ansible Galaxy. Если вы захотите использовать роль, написанную кем-то другим, или просто посмотреть, как кто-то решил похожую задачу, вам поможет Ansible Galaxy. Это хранилище ролей Ansible с открытым исходным кодом, пополняемое членами сообщества Ansible. Сами роли хранятся на GitHub.
Давайте познакомимся с инструментом ansible-galaxy. Проведём поиск по Galaxy и выберем подходящую роль из списка:
ansible-galaxy search "PHP for RedHat/CentOS/Fedora/Debian/Ubuntu"
Команда поиска выведет нечто подобное:
Предположим, мы выбрали роль geerlingguy.php. Чтобы загрузить её в наш плейбук, используем команду ansible-galaxy install:
ansible-galaxy install geerlingguy.php
После запуска вы команды вы увидите:
Теперь можем добавить роль в файл playbook.yml:
Запуск ansible-playbook playbook.yml с добавленной ролью Galaxy приведет к следующему результату:
Коротко о главном
Роли Ansible позволяют определить, как должны выглядеть ваши серверы. Они отделяют конфигурацию на уровне хоста от вашей задачи и обеспечивают чистоту и читаемость кода Ansible. Но, что самое главное — они позволяют повторно использовать код и обмениваться им, а также внедрять изменения контролируемым способом.
«DevOps Tools для разработчиков»
Больше об Ansible
Тех, кто хочет научиться управлять серверами и автоматизировать задачи с помощью Ansible, мы приглашаем на наш курс «Ansible: Infrastructure as Code», который пройдет с 23 января по 19 февраля.