ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE)
Понедельник, 31 марта, 2025
Сегодня у нас 1 праздник:
Международный День Резервного Копирования (World Backup Day). Пользователи сайта социальных новостей reddit предложили сделать дату 31.03 Международным днём резервного копирования, аргументируя это тем, что никогда заранее нельзя узнать, какие сюрпризы преподнесёт 1.04

Ansible. Роли в Ansible

Начало работы с Ansible

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

В этом руководстве вы поймете, как структурированы роли в Ansible. Вы также научитесь использовать готовые роли из Ansible Galaxy.

Кроме того, вы научитесь создавать свои собственные роли Ansible.

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

 

Понимание ролей Ansible

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

 

Структура каталога ролей

Типичная роль Ansible следует определенной структуре каталогов, которая обычно состоит из следующих каталогов:

  1. defaults: содержит переменные по умолчанию для роли, которые должны быть легко перезаписаны.
  2. vars: содержит стандартные переменные для роли, которые не должны быть перезаписаны в вашей книге.
  3. tasks: содержит набор задач, которые должна выполнять роль.
  4. handlers: содержит набор обработчиков, которые будут использоваться в роли.
  5. templates: содержит шаблоны Jinja2, которые будут использоваться в роли.
  6. files: содержит статические файлы, необходимые из ролевых задач.
  7. tests: может содержать дополнительный файл инвентаря, а также playbook test.yml, который можно использовать для тестирования роли.
  8. meta: содержит метаданные роли, такие как информация об авторе, лицензия, зависимости и т. д.

Имейте в виду, что у роли могут быть все вышеупомянутые каталоги или только их часть. Фактически, вы можете определить пустую роль, у которой нет каталогов, но это бесполезно!

 

Хранение и расположение ролей

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

  1. В каталоге role (тот же уровень каталога, что и ваш файл playbook).
  2. В каталоге /etc/ansible/roles.

Однако вы можете сохранить свои роли в другом месте; если вы решите это сделать, вы должны указать и установить параметр конфигурации roles_path в файле конфигурации Ansible ( ansible.cfg ).

 

Использование ролей Ansible в Playbooks

Есть два разных способа, которыми вы можете импортировать роли в пьесе Ansible :

  1. Использование ключевого слова roles для статического импорта ролей.
  2. Использование модуля 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 может установить сразу несколько ролей, используя файл требований.

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

Чтобы продемонстрировать это, создайте файл 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 в следующем порядке:

  1. pre_tasks будет запущен первым.
  2. обработчики, запускаемые pre_tasks, запускаются следующим образом.
  3. статически импортированные роли, перечисленные под ролями, будут выполняться.
  4. задачи, перечисленные в разделе задач.
  5. обработчики, запускаемые ролями или задачами.
  6. post_tasks будет выполняться последним.
  7. обработчики, запускаемые 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.

Exit mobile version