
Содержание
В предыдущей статье рассмотрели как управлять конфигурациями и как писать playbook. В этой (последней) части рассмотрим модули и как их применять, познакомимся с ролями.
Модули
Модуль можно написать на любом языке, он должен уметь принимать параметры на вход и выдавать json ответ. Модули находятся здесь.
Как написать свой собственный модуль, можно прочитать в документации.
В состав Ansible входит огромное количество модулей для развёртывания, контроля и управления различными компонентами, которые можно условно разделить на следующие группы (в скобках приведены названия некоторых продуктов и сервисов):
- облачные ресурсы и виртуализация (Openstack, libvirt);
- базы данных (MySQL, Postgresql, Redis, Riak);
- файлы (шаблонизация, регулярные выражения, права доступа);
- мониторинг (Nagios, monit);
- оповещения о ходе выполнения сценария (Jabber, Irc, почта, MQTT, Hipchat);
- сеть и сетевая инфраструктура (Openstack, Arista);
- управление пакетами (apt, yum, rhn-channel, npm, pacman, pip, gem);
- система (LVM, Selinux, ZFS, cron, файловые системы, сервисы, модули ядра);
- работа с различными утилитами (git, hg).
Командный модуль command
Модуль принимает имя команды и армументы. Переменные оболочки или операции (<,>,|,&) не будут работать с модулем command, т.к. обрабатываются оболочкой. Модуль command принимает следующие параметры:
- chdir: Используется для изменения текущей директории, в которой исполняется команда
- creates: Создает файл
- removes: Удаляет файл
Простейшая задача перезагрузки сервера:
- name: Reboot machine command: /sbin/shutdown -r now sudo: yes
Командный модуль raw
Этот модуль следует использовать, когда другие командные модули использовать не удается. Это простой запуск удаленных команд серверу по SSH. Данный модуль работает даже на серверах без установленного Python.
Пример установки пакета vim:
- name: Install vim raw: yum -y install vim-common sudo: yes
По окончанию выполнения операции, можно будет увидеть, что пакет установлен, но задача не будет помечена как changed. Лучше не использовать raw модуль когда возможно.
Командный модуль script
Этот модуль используется для копирования скрипта на удаленную машину и исполнения его. Модуль поддерживает параметры creates и removes.
Для примера, напишем скрипт для просмотра количества директорий в /etc и запустим его на удаленных серверах (~/ansible/playbooks/scripts/list_number_of_directories.sh)
#/bin/bash ls -l /etc | egrep '^d' | wc -l
Задача, использующая модуль script выглядит так:
- name: List directories in /etc script: ~/ansible/playbooks/scripts/list_number_of_directories.sh /etc sudo: yes
Путь к файлу скрипта задается относительно месторасположения файла, использующего модуль script. Например, если данная задача описана в файле задачи, импортированном в playbook, расположение скрипта задается относительно файла задачи, а не playbook.
Командный модуль shell
Ключевое отличие модуля shell от модуля command в том, что он использует /bin/sh по умолчанию для запуска команд. Вы можете использовать переменные оболочки и другие функции оболочки.
Файловый модуль file
Модуль file позволяет вам изменять атрибуты файла. Можно создать файл, создать или удалить директории рекурсивно, создать или удалить символическую ссылку.
Проверим, что httpd.conf имеет правильные права владельца:
- name: Ensure httpd conf has right permissions and owner/group file: path=/etc/httpd/conf/httpd.conf owner=root group=root mode=0644 sudo: yes
Так как скрипты Ansible позволяют достичь нужного состояния и при перезапуске скриптов - повторный запуск позволит убедиться и поправить при необходимости права на доступ к файлам.
Как создаются симлинки:
- name: Create a symlink in /tmp for httpd.conf file: src=/etc/httpd/conf/httpd.conf dest=/tmp/httpd.conf owner=root group=root state=link sudo: yes
Создание директории рекурсивно:
- name: Create recursive directories file: path=/tmp/dir1/dir2/dir3 owner=root group=root mode=0777 sudo: yes
Файловый модуль copy
С помощью модуля copy можно копировать файлы на сервер.
- name: Copy file remotely copy: src=test2.conf dest=/etc/test2.conf owner=root group=root mode=0644 sudo: yes
Модуль системы управления версиями git
В Ansible есть поддержка различных систем управления версиями (svn, bzr, hg и другие), но рассмотрим git:
Установка git на сервер:
- yum: name=git state=installed sudo: yes
Получим репозиторий со скриптами из этих статей:
- name: Checkout ansible–playground repository git: repo=https://github.com/trukhinyuri/ansible-playground.git dest=~/checkout sudo: yes
До и после выполнения задачи считается SHA, который позволяет понять, был ли репозиторий обновлен.
Если получаете файлы по SSH - используйте параметры accept_key и key_file для установки ключа для доступа к репозиторию. Если нужно использовать ключ accept_key=yes, key_file - указывает на путь к ключу. Если ключ находится в ~/.ssh - указывать key_file не нужно.
Роли
Ролью называется типовой набор переменных и задач, назначаемых для одного или нескольких серверов. Если вам нужно применить к серверу или группе серверов типовой набор операций, вам достаточно просто назначить ему роль. Предварительно в проекте каталоге проекта должна быть создана соответствующая структура. В сценариях роли назначаются следующим образом:
--- - hosts: webservers roles: - common - web – db
Файловая структура ролей будет выглядеть, примерно вот так:
site.yml webservers.yml roles/ common/ files/ templates/ tasks/ handlers/ vars/ defaults/ meta/ web/ files/ templates/ tasks/ handlers/ vars/ defaults/ meta/ db/ files/ templates/ tasks/ handlers/ vars/ defaults/ meta/
Если какой-то директории в роли нет - она будет проигнорирована и playbook будет исполняться. Совсем не обязательно у вас должны быть все элементы и директории playbook.
Правила, используемые для каждой роли:
- Если roles/x/tasks/main.yml существует, задачи будут добавлены в процесс исполнения playbook.
- Если roles/x/handlers/main.yml существует, обработчики событий будут добавлены в процесс исполнения playbook.
- Если roles/x/vars/main.yml существует, переменные будут добавлены в процесс исполнения playbook.
- Если roles/x/meta/mail.yml существует, любые роли-зависимости будут добавлены в список ролей. (В meta можно указывать список ролей, которые должны быть применены до конкретной роли, чтобы она применилась корректно).
- Любая задача копирования может ссылаться на файл в roles/x/files без указания абсолютного или относительного пути.
- Любая скриптовая задача может ссылаться на скрипты в roles/x/files без указания абсолютного или относительного пути.
- Любая задача шаблонизации может ссылаться на roles/x/templates без указания абсолютного или относительного пути.
- Любые импортируемые задачи могут ссылаться на файлы задач в директории roles/x/tasks без указания абсолютного или относительного пути.
В конфигурационном файле Аnsible можно задать roles_path (директорию с ролями). Это может пригодиться, если у вас playbook лежат в одном репозитории, а сами роли в другом. Можно задавать сразу несколько путей к ролям через двоеточие:
roles_path = /opt/mysite/roles:/opt/othersite/roles
В роли можно передавать переменные или использовать условия:
--- - hosts: experiments roles: – common – {role: web, dir: '/var/www', port: 80} – {role: repository, when: "ansible_os_family =='RedHat'"}
С помощью тегов можно запускать помеченные части playbook. Использование тэгов выглядит так:
tasks: - apt: name={{ item }} state=installed with_items: - httpd - htop tags: - packages - template: src=templates/src.j2 dest=/var/www/.htaccess tags: - configuration
Можно запустить часть playbook так: ansible-playbook example.yml --tags «configuration,packages» или пропустить исполнение части так: ansible-playbook example.yml --skip-tags «notification».
Тэги можно использовать и при указании ролей:
--- - hosts: experiments roles: - { role: web, tags: ["apache", "simple"] }
Можно указать, какие задачи должны выполниться до роли и после:
--- - hosts: experiments pre_tasks: - shell: echo 'hello, habr' roles: - { role: web } tasks: - shell: echo 'still busy' post_tasks: - shell: echo 'goodbye, habr'
Зависимости ролей
Зависимости ролей позволяют автоматически исполнить зависимые роли при запуске конкретных ролей, у которых зависимости есть. Зависимости хранятся в roles/x/meta/main.yml. Вместе с зависимыми ролями могут быть переданы параметры. Путь к ролям может быть указан как в сокращенном виде, так и в полном. Также может быть использован репозиторий системы управления версиями.
--- dependencies: - { role: common, some_parameter: 3 } - { role: '/path/to/common/roles/foo', x: 1 } - { role: 'git+http://git.example.com/repos/role-foo,v1.1,foo' }
Если в зависимостях указана одна и та же роль несколько раз - она запустится только однажды. Если нужно несколько раз, можно в файле зависимостей попросить об этом явно.