Ansible практика – урок №3: Ограничение работы плейбука с помощью tags и limit.

Предыдущий урок: Ansible практика – урок №2: Как запустить первый плейбук.

В прошлом уроке мы написали и успешно запустили свой первый плейбук. Ansible прошел по всем хостам и выполнил все задачи, которые мы перечислили в плейбуке.

Но что если нам, например, нужно подготовить еще один сервер? Перераскатывать при этом еще раз все старые сервера нет никакой необходимости. Или, например, мы хотим повторно выполнить только часть задач, а не весь плейбук целиком, что тогда?

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

Зачем нужен limit?

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

Зачем нужен tags?

Задачам (tasks) можно присваивать теги, далее, с использованием параметра tags, можно включать и исключать таски и исполнения. Перед тем, как перейти к практическому использованию тегов, нам нужно немного модифицировать наш плейбук.

После добавления тегов, install_lemp.yml имеет вид:

---
- hosts: all
  tasks:

  - name: "Install PHP"
    ansible.builtin.dnf:
      name:
        - php
        - php-cli
        - php-fpm
        - php-common
        - php-mbstring
        - php-curl
        - php-mysqlnd
        - php-json
        - php-xml
        - php-phar
        - php-pdo
        - php-gd
      state: latest
    tags:
      - installation
      - php

  - name: "Install NGINX"
    ansible.builtin.dnf:
      name: nginx
      state: latest
    tags:
      - installation
      - nginx

  - name: "Ensure NGINX is started and enabled"
    ansible.builtin.service:
      name: nginx
      state: started
      enabled: true
    tags:
      - start
      - nginx

  - name: "Install MariaDB"
    ansible.builtin.dnf:
      name: mariadb-server
      state: latest
    tags:
      - installation
      - mariad

  - name: "Ensure MariaDB is started and enabled"
    ansible.builtin.service:
      name: mariadb
      state: started
      enabled: true
    tags:
      - start
      - mariadb

Ограничение работы плейбука с помощью tags и limit

С модификацией плейбука мы закончили, и можем переходить к практике.

Шаг 1: Использование tags

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

Теги installation и start присвоены задачам, которые устанавливают и запускают сервисы соответственно.

Теги с названиями сервисов php, nginx и mariadb присвоены таскам, связанным с этими сервисами.

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

Представим, что мы хотим убедиться, что на всех хостах установлен PHP, остальные сервисы нас сейчас не интересуют. Запустим наш плейбук, ограничив исполнение тегом php:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --tags php

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

TASK [Install PHP] **********************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Managed-Node-2             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]#

Как видите, были исполнены два таска – Gathering Facts и Install PHP. Сбор фактов происходит всегда, если обратное не указано в явном виде. Сам тег назначен только одной задачи, которую Ansible и исполнил.

Попробуем использовать тег start, присвоенный таскам по запуску сервисов:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --tags start

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-1]

TASK [Ensure NGINX is started and enabled] **********************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-1]

TASK [Ensure MariaDB is started and enabled] ********************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Managed-Node-2             : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]#

Результат понятен, из плейбука были взяты только задачи  Ensure … is started and enabled.

Можно использовать несколько тегов одновременно, перечислим их через запятую:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --tags nginx,start

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

TASK [Install NGINX] ********************************************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-1]

TASK [Ensure NGINX is started and enabled] **********************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-1]

TASK [Ensure MariaDB is started and enabled] ********************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-1]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Managed-Node-2             : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]#

Достаточно хотя бы одного совпадения по тегам, чтобы задача пошла в исполнение. Install NGINX – совпадение с nginx; Ensure MariaDB is started and enabled – совпадение с start; Ensure NGINX is started and enabled – подпадает под оба тега.

Теги можно не только включать, но и исключать:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --skip-tags installation

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

TASK [Ensure NGINX is started and enabled] **********************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

TASK [Ensure MariaDB is started and enabled] ********************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Managed-Node-2             : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]#

Мы исключили все таски с тегом installation, в итоге плейбук пропустил все задачи на установку программ.

tags и skip-tags можно использовать совместно:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --tags installation --skip-tags php

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-1]

TASK [Install NGINX] ********************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

TASK [Install MariaDB] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Managed-Node-2             : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]#

Ansible выполнил таски с установкой пакетов (тег installation), но исключил тот, что имеет тег php.

При этом исключение имеет большую силу, если tags и skip-tags прямо противоречат друг другу, то таск исключается из исполнения:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --tags php --skip-tags php

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Managed-Node-2             : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]# 

Шаг 2: Использование limit

С тегами разобрались, осталось проверить, как работает limit. Тут все еще проще, если мы хотим раскатать плейбук на отдельный хост, укажите его с помощью limit:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --limit Managed-Node-1

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]

TASK [Install PHP] **********************************************************************************************************************************************************************************
ok: [Managed-Node-1]

TASK [Install NGINX] ********************************************************************************************************************************************************************************
ok: [Managed-Node-1]

TASK [Ensure NGINX is started and enabled] **********************************************************************************************************************************************************
ok: [Managed-Node-1]

TASK [Install MariaDB] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]

TASK [Ensure MariaDB is started and enabled] ********************************************************************************************************************************************************
ok: [Managed-Node-1]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]#

Ansible выполнил все задачи, но только на указанном сервере. В limit можно указывать несколько хостов через запятую:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --limit Managed-Node-1,Managed-Node-2

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

TASK [Install PHP] **********************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

TASK [Install NGINX] ********************************************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-1]

TASK [Ensure NGINX is started and enabled] **********************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

TASK [Install MariaDB] ******************************************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-1]

TASK [Ensure MariaDB is started and enabled] ********************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Managed-Node-2             : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]#

При лимитированнии можно указывать обратное множество – все кроме указанного хоста:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --limit '!Managed-Node-1'

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-2]

TASK [Install PHP] **********************************************************************************************************************************************************************************
ok: [Managed-Node-2]

TASK [Install NGINX] ********************************************************************************************************************************************************************************
ok: [Managed-Node-2]

TASK [Ensure NGINX is started and enabled] **********************************************************************************************************************************************************
ok: [Managed-Node-2]

TASK [Install MariaDB] ******************************************************************************************************************************************************************************
ok: [Managed-Node-2]

TASK [Ensure MariaDB is started and enabled] ********************************************************************************************************************************************************
ok: [Managed-Node-2]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-2             : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]#

Все хосты, кроме Managed-Node-1 были отработаны.

tags и limit можно использовать вместе:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --limit Managed-Node-1 --tags php

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]

TASK [Install PHP] **********************************************************************************************************************************************************************************
ok: [Managed-Node-1]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[root@Control-Node ansible]#

Ansible выполнил только таск с тегом php и только относительно указанной ноды.

Итоги:

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

Следующий урок: Ansible практика – урок №4: Использование условий when в плейбуке.