Иногда бывает полезным использование тэгов в большом playbook. Тэги необходимы для того чтобы выполнить именно определённые tasks из всего playbook.

Приведу несколько примеров, когда можно использовать тэги, или даже нужно:

  • Допустим у вас playbook из 20 - 30 задач (tasks) и вам нужно выполнить только 2 - 3 задачи, например, просто перезапустить сервис или установить какие-то пакеты. В таком случае вы назначаете этим задачам определённый тэг и запускаете его.
  • Ещё один пример это сделать один playbook в котором можно прописать задачи по управлению всеми сервисами, например, тэг для отключения сервиса PostgreSQL и тэг для его включения. Это позволит вам при необходимости управлять всеми сервисами.
Все файлы в статье вы можете найти в репозитории [github](https://github.com/tipoitkz/ansible-examples).


Как использовать

Для использования тэгов придётся выполнить следующие 2 шага:

  1. Задать задаче (task) тэг
  2. При запуске playbook указать этот тэг

Задать задаче (task) тэг

В качестве примера я буду использовать playbook по управлению сервисами. В playbook 2 задачи по управлению сервисом metricbeat, где один включает сервис и другой выключает. Для демонстрации я просто использую debug, понятное дело, что нужно использовать service. Обратите внимание на tags, их также может быть несколько для одной задачи.

vim tasks.yml
- hosts: localhost

  tasks:

    - name: Stop metricbeat
      debug:
        msg: Stop metricbeat
      tags:
        #тут наш тэг для остановки
        - stop metricbeat

    - name: Start metricbeat
      debug:
        msg: Start metricbeat
      tags:
        #тут наш тэг для запуска
        - start metricbeat

При запуске playbook указать этот тэг

Теперь нам осталось только запустить playbook с определённым тэгом. Для этого используем знакомую команду ansible-playbook и передаем опцию --tags. Опция --tags может принимать несколько значений, например --tags "tag1,tag2,tag3".

Для остановки используем тэг stop metricbeat.

ansible-playbook tasks.yml --tags="stop metricbeat"

TASK [Stop metricbeat] **************************************************************************************************************************
ok: [localhost] => {
    "msg": "Stop metricbeat"
}

Для запуска используем тэг start metricbeat.

ansible-playbook tasks.yml --tags="start metricbeat"

TASK [Start metricbeat] *************************************************************************************************************************
ok: [localhost] => {
    "msg": "Start metricbeat"
}

Какие задачи запустятся?

Если файл слишком большой или playbook писали не вы наверняка появится желание какие именно задачи запустятся при использование определённого тэга.

ansible-playbook tasks.yml --tags="start metricbeat" --list-tasks
playbook: tasks.yml

  play #1 (localhost): localhost        TAGS: []
    tasks:
      Start metricbeat  TAGS: [start metricbeat]

Используем роли

Для того чтобы задать тэг роли (role) нужно задавать тэг именно в playbook где вызываются эти роли.

Пример с использованием roles:

vim roles.yml
- hosts: localhost

  roles:

    - role: stop_metricbeat
      tags:
        #тут наш тэг для остановки
        - stop metricbeat

    - role: start_metricbeat
      tags:
        #тут наш тэг для запуска
        - start metricbeat
ansible-playbook roles.yml --tags="start metricbeat"

TASK [start_metricbeat : Start metricbeat] ******************************************************************************************************
ok: [localhost] => {
    "msg": "Start metricbeat"
}

TASK [start_metricbeat : Start service2] ********************************************************************************************************
ok: [localhost] => {
    "msg": "Start service2"
}

Пример с использованием import_role:

vim import_role.yml
- hosts: localhost

  tasks:

    - import_role:
        name: stop_metricbeat
      tags:
        #тут наш тэг для остановки
        - stop metricbeat

    - import_role: 
        name: start_metricbeat
      tags:
        #тут наш тэг для запуска
        - start metricbeat

Наследование тэгов

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

Если вам вдруг нужно добавить наследование тэга для можно воспользоваться include_tasks или include_role добавляя apply.

vim include_tasks.yml
- hosts: localhost

  tasks:

    - include_tasks:
        file: roles/start_metricbeat/tasks/main.yml
        apply:
          tags: start metricbeat
      tags:
        #тут наш тэг для остановки
        - start metricbeat

    - include_tasks:
        file: roles/stop_metricbeat/tasks/main.yml
        apply:
          tags: stop metricbeat
      tags:
        #тут наш тэг для запуска
        - stop metricbeat
ansible-playbook include_tasks.yml --tags="stop metricbeat"
TASK [include_tasks] ****************************************************************************************************************************
included: /home/admin/ansible-examples/tags/roles/stop_metricbeat/tasks/main.yml for localhost

TASK [Stop metricbeat] **************************************************************************************************************************
ok: [localhost] => {
    "msg": "Stop metricbeat"
}

TASK [Stop service2] ****************************************************************************************************************************
ok: [localhost] => {
    "msg": "Stop service2"
}

Мы видим, что в итоге у нас остановились оба сервиса хотя, как и в случае с Используем роли, но тут немного другой расклад. Тут выполнились обе задачи в роли потому что мы добавили ко всем задачам в роле stop_metricbeat тэг stop metricbeat, используя apply.

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

vim include_tasks_without_apply.yml
- hosts: localhost

  tasks:

    - include_tasks:
        file: roles/start_metricbeat/tasks/main.yml
      tags:
        #тут наш тэг для остановки
        - start metricbeat

    - include_tasks:
        file: roles/stop_metricbeat/tasks/main.yml
      tags:
        #тут наш тэг для запуска
        - stop metricbeat
ansible-playbook include_tasks_without_apply.yml --tags="stop metricbeat"

TASK [include_tasks] ****************************************************************************************************************************
included: /home/admin/ansible-examples/tags/roles/stop_metricbeat/tasks/main.yml for localhost

TASK [Stop metricbeat] **************************************************************************************************************************
ok: [localhost] => {
    "msg": "Stop metricbeat"
}

Зарезервированные тэги

Ansible предоставляет 2 зарезервированных тэга:

  • always - задачи с этим тэгом будут выполнятся всегда, в независимости от того какой тэг вы указали при запуске. Убрать это поведение можно используя опцию --skip-tags always.
  • never - не трудно догадаться что тут обратная история задачи с этим тэгом не будут выполняться только если вы не укажете конкретно --tags never.
vim always.yml
- hosts: localhost

  tasks:

    - name: Stop metricbeat
      debug:
        msg: Stop metricbeat
      tags: [stop metricbeat,always]
        #тут наш тэг для остановки

    - name: Start metricbeat
      debug:
        msg: Start metricbeat
      tags:
        #тут наш тэг для запуска
        - start metricbeat
ansible-playbook always.yml --tags="start metricbeat"
TASK [Stop metricbeat] **************************************************************************************************************************
ok: [localhost] => {
    "msg": "Stop metricbeat"
}

TASK [Start metricbeat] *************************************************************************************************************************
ok: [localhost] => {
    "msg": "Start metricbeat"
}

vim never.yml
- hosts: localhost

  tasks:

    - name: Stop metricbeat
      debug:
        msg: Stop metricbeat
      tags: [never]
        #тут наш тэг для остановки

    - name: Start metricbeat
      debug:
        msg: Start metricbeat
      tags:
        #тут наш тэг для запуска
        - start metricbeat
ansible-playbook never.yml
TASK [Start metricbeat] *************************************************************************************************************************
ok: [localhost] => {
    "msg": "Start metricbeat"
}