Ansible. Роли в Ansible

До сих пор вы создавали сценарии Ansible для автоматизации определенной задачи на управляемых узлах. Существует огромная вероятность, что кто-то другой уже разработал Ansible-решение проблемы/задачи, которую вы пытаетесь решить, и именно в этом суть ролей Ansible.
В этом руководстве вы поймете, как структурированы роли в Ansible. Вы также научитесь использовать готовые роли из Ansible Galaxy.
Кроме того, вы научитесь создавать свои собственные роли Ansible.
Прежде чем приступить к изучению этой статьи, обратитесь к другим главам серии руководств по Ansible, чтобы лучше понять различные темы, упомянутые здесь.
Понимание ролей Ansible
Роль Ansible — это набор файлов, задач, шаблонов, переменных и обработчиков, которые вместе служат определенной цели, например, для настройки службы. Роли позволяют легко повторно использовать код и делиться решениями Ansible с другими пользователями, что делает работу с большими средами более управляемой.
Структура каталога ролей
Типичная роль Ansible следует определенной структуре каталогов, которая обычно состоит из следующих каталогов:
- defaults: содержит переменные по умолчанию для роли, которые должны быть легко перезаписаны.
- vars: содержит стандартные переменные для роли, которые не должны быть перезаписаны в вашей книге.
- tasks: содержит набор задач, которые должна выполнять роль.
- handlers: содержит набор обработчиков, которые будут использоваться в роли.
- templates: содержит шаблоны Jinja2, которые будут использоваться в роли.
- files: содержит статические файлы, необходимые из ролевых задач.
- tests: может содержать дополнительный файл инвентаря, а также playbook test.yml, который можно использовать для тестирования роли.
- meta: содержит метаданные роли, такие как информация об авторе, лицензия, зависимости и т. д.
Имейте в виду, что у роли могут быть все вышеупомянутые каталоги или только их часть. Фактически, вы можете определить пустую роль, у которой нет каталогов, но это бесполезно!
Хранение и расположение ролей
По умолчанию Ansible будет искать роли в двух местах:
- В каталоге role (тот же уровень каталога, что и ваш файл playbook).
- В каталоге /etc/ansible/roles.
Однако вы можете сохранить свои роли в другом месте; если вы решите это сделать, вы должны указать и установить параметр конфигурации roles_path в файле конфигурации Ansible ( ansible.cfg ).
Использование ролей Ansible в Playbooks
Есть два разных способа, которыми вы можете импортировать роли в пьесе Ansible :
- Использование ключевого слова roles для статического импорта ролей.
- Использование модуля include_role для динамического импорта ролей.
Например, чтобы статически импортировать роли в playbook, вы можете использовать ключевое слово роли в заголовке playbook следующим образом:
---
- name: Including roles statically
hosts: all
roles:
- role1
- role2
Динамически импортировать роли; вы можете использовать модуль include_role следующим образом:
---
- name: Including roles dynamically
hosts: all
tasks:
- name: import dbserver role
include_role:
name: db_role
when: inventory_hostname in groups['dbservers']
Использование Ansible Galaxy для готовых ролей
Представьте себе место, где все нужные вам роли Ansible уже предоставляются бесплатно; Это место называется Ansible Galaxy и оно реально!
Ansible Galaxy — это общедоступный веб-сайт, на котором предлагаются роли, предоставленные сообществом. По сути, это публичный репозиторий, в котором размещается огромное количество ролей Ansible. Мы рекомендуем вам посетить сайт Ansible Galaxy galaxy.ansible.com и ознакомиться с его потрясающим контентом.
Поиск ролей
В Ansible Galaxy есть собственная утилита CLI (интерфейс командной строки), и вы можете использовать ее для выполнения операций, связанных с ролями.
Например, вы можете найти роль в репозитории Galaxy с помощью команды поиска ansible-galaxy следующим образом:
[destroyer@control plays]$ ansible-galaxy search mariadb Found 370 roles matching your search: Name Description ---- ----------- 0x_peace.mariadb Mariadb role 5003.mariadb SQL Server relational database > aalaesar.install_nextcloud Add a new Nextcloud instance in> aalaesar.upgrade-nextcloud Upgrade an Nextcloud instance i> aaronpederson.mariadb MariaDB - An enhanced, drop-in > acandid.mariadb Install and Configure MariaDB 1> acandid.mariadb_apache_wordpress Install and Configure MariaDB, > acandid.mariadb_galera_cluster Install and Configure MariaDB G> acandid.zabbix Install Zabbix 4.2 Server achaussier.mariadb-server Ansible role to install MariaDB> adfinis-sygroup.mariadb Install and manage mariadb/mysq> AdnanHodzic.containerized-wordpress Deploy & run Docker Compose pro> ajeeshbas.ansible_role_mariadb your description alainvanhoof.alpine_mariadb MariaDB for Alpine Linux alexandrem.mariadb MariaDB server role alexeymedvedchikov.galera An ansible role for Galera Mari> alexfeig.guacamole Ansible role for installing Apa> alikins.mysql MySQL server for RHEL/CentOS an> geerlingguy.mysql MySQL server for RHEL/CentOS an
Как вы видете; в нем перечислены все роли galaxy, связанные с моим поисковым запросом mariadb.
Получение информации о ролях
Вы можете использовать команду ansible-galaxy info для отображения информации о роли.
Например, на основе результатов поиска, которые вы получили ansible-galaxy search mariadb; вы можете получить дополнительную информацию о роли geerlingguy.mysql:
[destroyer@control ~]$ ansible-galaxy info geerlingguy.mysql
Role: geerlingguy.mysql
description: MySQL server for RHEL/CentOS and Debian/Ubuntu.
active: True
commit: 0a354d6ad1e4f466aad5f789ba414f31b97296fd
commit_message: Switch to travis-ci.com.
commit_url: https://api.github.com/repos/geerlingguy/ansible-role-mysql>
company: Midwestern Mac, LLC
created: 2014-03-01T03:32:33.675832Z
download_count: 1104067
forks_count: 665
github_branch: master
github_repo: ansible-role-mysql
github_user: geerlingguy
id: 435
imported: 2020-10-29T19:36:43.709197-04:00
is_valid: True
issue_tracker_url: https://github.com/geerlingguy/ansible-role-mysql/is>
license: license (BSD, MIT)
min_ansible_version: 2.4
modified: 2020-10-29T23:36:43.716291Z
open_issues_count: 24
Как вы видете; Он показал вам подробное описание роли geerlingguy.mysql.
Установка и использование ролей
Прежде чем я покажу вам, как установить роли Ansible Galaxy; Теперь создайте новый каталог ролей в каталоге вашего проекта (plays):
[destroyer@control plays]$ mkdir roles
Теперь вы можете использовать команду ansible-galaxy install для установки роли geerlingguy.mysql следующим образом:
[destroyer@control plays]$ ansible-galaxy install geerlingguy.mysql -p ./roles - downloading role 'mysql', owned by geerlingguy - downloading role from https://github.com/geerlingguy/ansible-role-mysql/archive/3.3.0.tar.gz - extracting geerlingguy.mysql to /home/destroyer/plays/roles/geerlingguy.mysql - geerlingguy.mysql (3.3.0) was installed successfully
Обратите внимание, что мы использовали параметр -p, чтобы указать путь, по которому мы хотим установить роль. По умолчанию Ansible Galaxy устанавливает роль в каталог ~/.ansible/roles.
Теперь перейдите в каталог ролей и перечислите содержимое каталога ролей geerlingguy.mysql:
[destroyer@control plays]$ cd roles/
[destroyer@control roles]$ ls
geerlingguy.mysql
[destroyer@control roles]$ tree geerlingguy.mysql/
geerlingguy.mysql/
├── defaults
│ └── main.yml
├── handlers
│ └── main.yml
├── LICENSE
├── meta
│ └── main.yml
├── README.md
├── tasks
│ ├── configure.yml
│ ├── databases.yml
│ ├── main.yml
│ ├── replication.yml
│ ├── secure-installation.yml
│ ├── setup-Debian.yml
│ ├── setup-RedHat.yml
│ ├── users.yml
│ └── variables.yml
├── templates
│ ├── my.cnf.j2
│ ├── root-my.cnf.j2
│ └── user-my.cnf.j2
└── vars
├── Archlinux.yml
├── Debian-10.yml
├── Debian.yml
├── RedHat-6.yml
├── RedHat-7.yml
└── RedHat-8.yml
8 directories, 26 files
Как вы видете; geerlingguy.mysql роль следует стандартной структуре каталогов, что мы показали вам ранее.
Теперь давайте вернемся в каталог plays и создать новый PlayBook с именем MySQL-role.yml, который прикладывает роль geerlingguy.mysql на группу хоста dbservers:
[destroyer@control plays]$ cat mysql-role.yml
---
- name: Applying geerlingguy.mysql role
hosts: dbservers
roles:
- geerlingguy.mysql
Теперь запустите playbook:
[destroyer@control plays]$ ansible-playbook mysql-role.yml PLAY [Applying geerlingguy.mysql role] ***************************************** TASK [Gathering Facts] ********************************************************* ok: [node4] TASK [geerlingguy.mysql : include_tasks] *************************************** included: /home/destroyer/plays/roles/geerlingguy.mysql/tasks/variables.yml for node4 TASK [geerlingguy.mysql : Include OS-specific variables.] ********************** ok: [node4] => (item=/home/destroyer/plays/roles/geerlingguy.mysql/vars/Debian.yml) TASK [geerlingguy.mysql : Define mysql_packages.] ****************************** ok: [node4] TASK [geerlingguy.mysql : Define mysql_daemon.] . . . RUNNING HANDLER [geerlingguy.mysql : restart mysql] **************************** PLAY RECAP ********************************************************************* node4 : ok=32 changed=10 unreachable=0 failed=0 skipped=12
После того, как playbook будет запущен; mysql должен быть запущен на node4:
[destroyer@control plays]$ ansible node4 -m command -a "systemctl status mysql"
node4 | CHANGED | rc=0 >>
● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2020-11-10 23:31:51 UTC; 7min ago
Process: 26544 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid (code=exited, status=0/SUCCESS)
Process: 26524 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 26546 (mysqld)
Tasks: 28 (limit: 2265)
CGroup: /system.slice/mysql.service
└─26546 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
Nov 10 23:31:39 node4 systemd[1]: Starting MySQL Community Server...
Nov 10 23:31:51 node4 systemd[1]: Started MySQL Community Server.
Если вам больше не нужна роль; вы можете удалить его с помощью команды ansible-galaxy remove следующим образом:
[destroyer@control plays]$ ansible-galaxy remove geerlingguy.mysql -p ./roles - successfully removed geerlingguy.mysql
Использование файла требований для установки нескольких ролей
Ansible galaxy может установить сразу несколько ролей, используя файл требований.
Каждая роль, которую вы определяете в своем файле требований, будет иметь еще один из следующих атрибутов:
- src: источник роли (обязательный атрибут).
- scm: если src является URL-адресом, укажите SCM. По умолчанию git; Поддерживаются только git и hg. (по желанию)
- имя: загрузка роли с определенным именем. По умолчанию используется имя Galaxy или имя репозитория при загрузке с git. (по желанию)
- версия: версия роли для загрузки. По умолчанию используется основная версия. (по желанию)
Чтобы продемонстрировать это, создайте файл requirements.yml со следующими тремя ролями:
[destroyer@control plays]$ cat requirements.yml # From Ansible Galaxy - src: geerlingguy.haproxy # From Github - src: https://github.com/bennojoy/nginx name: nginx_role version: master # From Ansible Galaxy - src: geerlingguy.jenkins name: jenkins_role
Теперь вы можете использовать команду установки ansible-galaxy вместе с параметром -r, чтобы установить три роли в вашем файле requirements.yml:
[destroyer@control plays]$ ansible-galaxy install -r requirements.yml -p ./roles - downloading role 'haproxy', owned by geerlingguy - downloading role from https://github.com/geerlingguy/ansible-role-haproxy/archive/1.1.2.tar.gz - extracting geerlingguy.haproxy to /home/destroyer/plays/roles/geerlingguy.haproxy - geerlingguy.haproxy (1.1.2) was installed successfully - extracting nginx_role to /home/destroyer/plays/roles/nginx_role - nginx_role (master) was installed successfully - downloading role 'jenkins', owned by geerlingguy - downloading role from https://github.com/geerlingguy/ansible-role-jenkins/archive/4.3.0.tar.gz - extracting jenkins_role to /home/destroyer/plays/roles/jenkins_role - jenkins_role (4.3.0) was installed successfully
Как вы видете; три роли, определенные в файле requirements.yml, успешно установлены. Вы также можете использовать список ansible-galaxy, чтобы перечислить установленные роли вместе с их версиями:
[destroyer@control plays]$ ansible-galaxy list -p ./roles # /home/destroyer/plays/roles - geerlingguy.haproxy, 1.1.2 - nginx_role, master - jenkins_role, 4.3.0
Создание пользовательских ролей
Вы также можете определить свои собственные роли. Для этого вы можете использовать команду ansible-galaxy init, чтобы определить структуру ролей.
Для демонстрации давайте создадим новую роль с именем httpd-role. Сначала перейдите в каталог ролей, а затем запустите команду ansible-galaxy init, за которой следует новое имя роли, как показано ниже:
[destroyer@control plays]$ cd roles/ [destroyer@control roles]$ ansible-galaxy init httpd-role - Role httpd-role was created successfully
Обратите внимание, что была создана новая роль с именем httpd-role, и в ней есть все типичные каталоги ролей.
[destroyer@control roles]$ tree httpd-role/
httpd-role/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
8 directories, 8 files
Теперь начните определять задачи, шаблоны и переменные по умолчанию для новой роли httpd.
Во-первых, вы можете начать с определения задач, отредактировав файл tasks/main.yml так, чтобы он содержал следующее содержимое:
[destroyer@control httpd-role]$ cat tasks/main.yml
---
# tasks file for httpd-role
- name: Install httpd
yum:
name: httpd
state: latest
- name: Start and enable httpd
service:
name: httpd
state: started
enabled: true
- name: Create index.html using Jinja2
template:
src: index.j2
dest: /var/www/html/index.html
Затем вы можете создать файл шаблона Jinja2 index.j2 внутри каталога шаблонов роли:
[destroyer@control httpd-role]$ cat templates/index.j2
Welcome to {{ inventory_hostname }}
This is an Apache Web Server.
Please contact {{ sysadmin }} for any questions or concerns.
Наконец, вы можете определить и установить переменную sysadmin в defaults/main.yml:
[destroyer@control httpd-role]$ cat defaults/main.yml --- # defaults file for httpd-role sysadmin: destroyer@andreyex.ru
Хорошо! Теперь вы закончили создание роли. Давайте создадим сценарий, в котором используется httpd-role.
Вернитесь в каталог проекта и создайте playbook apache-role.yml со следующим содержимым:
[destroyer@control plays]$ cat apache-role.yml
---
- name: Using httpd-role
hosts: webservers
roles:
- role: httpd-role
sysadmin: angela@andreyex.ru
Обратите внимание, что вы перезаписали переменную sysadmin в playbook. Идите вперед и запустите playbook:
[destroyer@control plays]$ ansible-playbook apache-role.yml PLAY [Using httpd-role] ****************************** TASK [Gathering Facts] ************************************** ok: [node2] ok: [node3] TASK [httpd-role : Install httpd] ********************* changed: [node2] changed: [node3] TASK [httpd-role : Start and enable httpd] ******************** changed: [node2] changed: [node3] TASK [httpd-role : Create index.html using Jinja2] **************** changed: [node2] changed: [node3] PLAY RECAP ****************** node2 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 node3 : ok=4 changed=3 unreachable=0 failed=0 skipped=0
Все выглядит хорошо. Давайте проверим, проверив ответ, который вы получаете на обоих веб-серверах ( node2 и node3 ):
[destroyer@control plays]$ curl node2 Welcome to node2 This is an Apache Web Server. Please contact angela@andreyex.ru for any questions or concerns. [destroyer@control plays]$ curl node3 Welcome to node3 This is an Apache Web Server. Please contact angela@andreyex.ru for any questions or concerns.
Отлично! Ваша заказная httpd-роль работала безупречно.
Если вы когда-нибудь создадите потрясающую роль Ansible, которая, по вашему мнению, принесет пользу многим; не забудьте опубликовать свою роль в Ansible Galaxy, чтобы поделиться ею со всем миром!
Управление порядком выполнения задач
Вы должны хорошо знать порядок выполнения задач в сценарии Ansible.
Если вы используете ключевую работу ролей для статического импорта роли; тогда все задачи в этой роли будут выполняться перед всеми другими задачами (включенными в раздел задач) в вашей игре.
Вы можете использовать ключевое слово pre_tasks, чтобы включить любые задачи, которые вы хотите запустить перед статически импортированными ролями. Вы также можете использовать ключевое слово post_tasks, чтобы включить любые задачи, которые вы хотите запустить после всех задач в разделе задач .
Таким образом, Ansible выполняет playbook в следующем порядке:
- pre_tasks будет запущен первым.
- обработчики, запускаемые pre_tasks, запускаются следующим образом.
- статически импортированные роли, перечисленные под ролями, будут выполняться.
- задачи, перечисленные в разделе задач.
- обработчики, запускаемые ролями или задачами.
- post_tasks будет выполняться последним.
- обработчики, запускаемые post_tasks, будут работать последними.
Для демонстрации взгляните на следующую книгу pre-post.yml, в которой используются pre_tasks, роли, задачи и post_tasks:
[destroyer@control plays]$ cat pre-post.yml
---
- name: Understanding Order of Task Execution
hosts: node1
tasks:
- name: A regular task
debug:
msg: "I am just a regular task."
post_tasks:
- name: Runs last
debug:
msg: "I will run last (post_task)."
pre_tasks:
- name: Runs first
debug:
msg: "I will run first (pre_task)."
roles:
- role: myrole
В сборнике plays используется созданная мной роль myrole, которая выполняет две простые задачи:
[destroyer@control plays]$ tree roles/myrole
roles/myrole
└── tasks
└── main.yml
1 directory, 1 file
[destroyer@control plays]$ cat roles/myrole/tasks/main.yml
- name:
debug:
msg: “I am the first task in myrole.”
- name:
debug:
msg: “I am the second task in myrole.”
Теперь запустите playbook:
[destroyer@control plays]$ ansible-playbook pre-post.yml
PLAY [Understanding Order of Task Execution] *************
TASK [Gathering Facts] *********************************
ok: [node1]
TASK [Runs first] ***************************
"msg": "I will run first (pre_tasks)."
}
TASK [myrole : debug] *******************************
ok: [node1] => {
"msg": "I am the first task in myrole."
}
TASK [myrole : debug] *************************
ok: [node1] => {
"msg": "I am the second task in myrole."
}
TASK [A regular task] ***************************
ok: [node1] => {
"msg": "I am just a regular task."
}
TASK [Runs last] ******************************
ok: [node1] => {
"msg": "I will run last (post_tasks)."
}
PLAY RECAP *******************************
node1 : ok=6 changed=0 unreachable=0 failed=0 skipped=0
Как вы видите, сначала выполняется pre_tasks, затем две задачи в myrole, затем задачи и, наконец, последними запускаются post_tasks.
Надеюсь, вам понравилось узнавать, как использовать и создавать роли Ansible.
Редактор: AndreyEx