Ansible теги может использоваться для выполнения только подмножества задач / ролей. Это означает, что по умолчанию все задачи выполняются, и мы можем предотвратить выполнение только некоторых задач.
Можем ли мы ограничить выполнение задачи? только когда указан тег "foo"? Можем ли мы использовать текущие теги в when
раздел задачи?
В Ansible 2.5 есть специальные теги never
и always
. Тег never
можно использовать именно для этой цели. Например:
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'never', 'debug' ]
В этом примере задача будет запущена только тогда, когда debug
(или never
) явно запрашивается. [Ссылка на доступные документы]
Хотя это обходное решение, оно работает.
Внутри списка задач зарегистрируйте переменную при нормальном выполнении. Затем добавьте условие when, которое проверяет эту переменную, в помеченную задачу.
- shell: /bin/true
register: normal_task_list
- name: Only run when tag is specified
shell: /bin/echo "Only running because of specified tag"
when: normal_task_list is not defined
tags: specified
У меня недостаточно репутации, чтобы проголосовать за или прокомментировать ответ, предлагающий использовать переменные командной строки (--extra-vars
), но я могу добавить к нему следующее:
Предостережение к этому методу заключается в том, что воспроизведение будет ошибочным и завершится ошибкой, если вы не определите эту дополнительную переменную.
Вы можете предотвратить проигрыш при отсутствии --extra-vars
определение путем определения значения по умолчанию в самом playbook:
---
- hosts: ...
# ↓↓↓
vars:
thorough: false
# ↑↑↑
tasks:
- name: apt - install nfs-common only when thorough is true
when: thorough | bool
apt:
cache_valid_time: 86400
force: yes
pkg:
- nfs-common
Переопределение через --extra-vars
будет по-прежнему работать, потому что переменные, определенные в командной строке, имеют приоритет над всеми другими определениями.
В результате игра проходит без ошибок, когда thorough
не меняется на true
в командной строке.
Ты можешь использовать Условные для защиты от случайно запущенных задач, которые в противном случае были бы выполнены, если вы не укажете тег. Предостережение к этому методу заключается в том, что воспроизведение будет ошибочным и завершится ошибкой, если вы не определите эту дополнительную переменную.
Используя аргумент extra-vars, вы можете инициировать выполнение вашего условного оператора.
Из ansible-playbook --help:
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
set additional variables as key=value or YAML/JSON
Пример:
ansible-playbook test.yaml -e "thorough=true"
test.yaml:
...
- name: apt - install nfs-common only when thorough is true
apt:
cache_valid_time: 86400
force: yes
pkg:
- nfs-common
when: thorough | default(False)
...
Проверка переменной 'tags' не работает в Ansible 2.1.1.0. Смотрите ниже тест. У меня есть другая идея выполнять задачу только тогда, когда тег определен, работающий как для Ansible 1.9.X, так и для 2.X.Y:
- set_fact: foo=true
tags: bar
- set_fact: foo=false
- name: do something when 'bar' tag is defined
debug: var=foo
when: foo
tags: bar
При этом при запуске playbook без тега переменная foo будет установлена в true, а затем в false, поэтому ничего не будет выполнено. Если вы добавите тег 'bar', будет применен только первый параметр, поэтому переменная 'foo' будет истинной, тогда ваша задача будет выполнена. Наслаждайтесь!
И вот тест о переменной 'tags' в Ansible 2.1.1.0:
Вот инструкция:
- hosts: localhost
connection: local
tasks:
- name: display tags variable
debug: var=tags
tags: foo
- name: do something only when tag 'foo' is provided
debug: var=tag
when: tags is defined
tags: foo
И вот результат:
$ ansible-playbook --version ; ansible-playbook ./test.yml -t foo
ansible-playbook 2.1.1.0
config file = /home/nootal/projects/ivy/src/ansible/ansible.cfg
configured module search path = Default w/o overrides
PLAY [localhost] ***************************************************************
TASK [display tags variable] ***************************************************
ok: [localhost] => {
"tags": "VARIABLE IS NOT DEFINED!"
}
TASK [do something only when tag 'foo' is provided] ****************************
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0
Есть специальный тег - "никогда", что предотвратит запуск задачи, если не будет специально запрошен тег.
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'never', 'debug' ]
Да. Запуск ansible-playbook с --tags foo
флаг гарантирует, что только задачи, помеченные foo
выполнены. Например, предположим, что у нас есть учебник под названием example.yml:
tasks:
- yum: name={{ item }} state=installed
with_items:
- httpd
- memcached
tags:
- packages
- name: some other task
..
tags:
- some other tag
Бег:
ansible-playbook example.yml --tags "packages"
Убедится, что выполняется только задача yum.
Так что на самом деле вам не нужно использовать теги в разделе when для условного выполнения задачи. Обратите внимание, что в зависимости от сложности ваших сценариев / ролей вам может потребоваться комбинация --tags и --skip-tags для управления тем, какие задачи выполняются. Например, если включаемые задачи помечены как 'foo', а какая-то задача внутри включенной книги воспроизведения помечена как 'bar', и вы запускаете
ansible-playbook --tags "foo"
Внутренняя задача (помеченная только как «бар») будет выполнена. Чтобы избежать выполнения всех внутренних задач, помеченных как 'bar', вам нужно будет выполнить следующую команду
ansible-playbook --tags foo --skip-tags bar
Возможно, более идиоматичный и элегантный способ - добавить when
условие к задаче, например:
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'debug' ]
when: "'debug' in ansible_run_tags"
Это использует магическая переменная ansible_run_tags
который содержит список тегов, переданных через аргумент CLI --tags
(или синонимично -t
) и имеет эффект выполнения вышеуказанной задачи если и только если тег debug
дано.
Кажется, эта волшебная переменная была введена в ansible 2.5
когда предложение не может оценивать наличие тегов. В качестве обходного пути я использую переменные и теги вместе для выполнения задач, специфичных для этого тега / переменной.
Пример: представьте себе пьесу и инвентарь.
# inventory [dev] 192.168.1.1 # site.yml - hosts: dev roles: - { role: common } and in common/tasks/main.yml # roles/common/tasks/main.yaml - name: Install links apt: name=links state=present - include: uninstall.yml when: uninstall_links is defined tags: - uninstall # roles/common/tasks/uninstall.yml - name: Uninstall links apt: name=links state=absent
При таком подходе вы используете тег для выбора только задач в uninstall.yml, но вам также необходимо установить переменную «uninstall_links» на что-нибудь, чтобы включить ее. Поэтому, если вы запустите playbook без каких-либо параметров, он по умолчанию запустит задачу установки. Для удаления вы можете установить тег «uninstall» для своей playbook (или cmdline) и ДОЛЖЕН установить переменную. Если вы не установите тег, он запустит все (установку и удаление) в указанном порядке, что хорошо для тестирования всего процесса.
Как все запустить (установит и деинсталлирует):
$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true"
Как запустить только тег удаления в группе разработчиков
$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true" -t uninstall
Следовательно, переменные и теги также могут быть в файлах site.yml / inventory, что позволит вам выполнить фиксацию в SCM и записать свое намерение.
nootal прав, мой подход не работает - игнорировать это :( Теперь я использую "when: myvar is defined" и переключатель командной строки "-e" myvar = X "для выполнения задач только по явному запросу.
Еще проще (по крайней мере, с доступным 2.1.1.0):
- name: do something only when tag 'foo' is provided
when: tags is defined
tags: foo
-> будет выполняться, только если теги были предоставлены И теги включают "foo"
На Ansible 2.3.2.0
, вот мое решение проблемы:
---
- hosts: localhost
gather_facts: no
vars:
in_tag: yes
tasks:
- set_fact: in_tag=no
- fail:
msg: "recently_added is set and you're using blah tag"
when: ( in_tag | bool )
tags:
- blah
- debug:
msg: "always remember"
Он начинается с установки in_tag
к True
тогда есть set_fact
это возвращает его к False
когда вы не указываете tags
из ansible-playbook
.
Когда вы указываете теги, in_tag
остается в True
и fail
задача выполняется.
PS: вы можете добавить логику к любым задачам, которые хотите
PS2: вы также можете расширить логику и жестко закодировать все теги, которые у вас есть, и set_fact: in_tag_blah=True
в комбинации с tags: ["blah"]
конечно.
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'never', 'debug' ]
Это правильный ответ, но людей часто смущает то, как заставить Ansible Добавить этот тег, потому что если вы поместите --tags debug
в командной строке, затем только то, что выполняется, - это задачи отладки. Решение --tags all,debug
например
ansible-playbook play.yaml --tags all,debug
В Ansible docs по тегам есть эта строка:
По умолчанию Ansible запускается так, как если бы были указаны --tags all.