Ansible: Выполните задачу только, когда тег будет указан

Теги Ansible могут использоваться для выполнения только подмножества задач/ролей. Это означает, что по умолчанию все задачи выполняются, и мы можем только предотвратить некоторые задачи выполниться.

Мы можем ограничить задачу быть exectued только, когда тег "нечто" указан? Мы можем использовать текущие теги в when раздел задачи?

75
задан 13 February 2018 в 10:49
13 ответов

I-Ansible 2.5 iza neethegi ezizodwa zange kwaye njalo . I-Tag ayisoze inokusetyenziselwa le njongo kanye. Umzekelo:

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]

Kulo mzekelo, umsebenzi uya kusebenza kuphela xa debug (okanye zange tag ithegi iceliwe ngokucacileyo. [Reference on ansible docs]

38
ответ дан 28 November 2019 в 19:27

Да. Запуск 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

running:

ansible-playbook example.yml --tags "packages"

Will sure only the yum task is performed.

So actually you don't really need to use tags in when section to conditionally execution a task. Обратите внимание, что в зависимости от сложности ваших плейбуков/ролей вам может понадобиться использовать комбинацию --tags и --skip-tags для управления тем, какие задачи выполняются. Например, если включенные задачи помечены как 'foo', а какая-то задача внутри включенного учебника воспроизведения помечена как 'bar' и вы запускаете

ansible-playbook --tags "foo"

Внутренняя задача (помеченная только как 'bar') будет выполнена. Чтобы избежать выполнения всех внутренних задач, помеченных как 'bar', Вы должны выполнить следующую команду

ansible-playbook --tags foo --skip-tags bar
1
ответ дан 28 November 2019 в 19:27

У меня недостаточно репутации, чтобы проголосовать за или прокомментировать ответ, предлагающий использовать переменные командной строки ( - 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 по-прежнему будет работать, потому что переменные, определенные в командной строке, имеют приоритет над всеми другими определениями.

В результате воспроизведение выполняется без ошибок, если тщательный не изменен на true в командной строке.

17
ответ дан 28 November 2019 в 19:27

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

Используя аргумент extra-vars, вы можете инициировать выполнение вашего условного оператора.

From 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)
...
10
ответ дан 28 November 2019 в 19:27

Хотя это обходное решение, оно работает.

Внутри списка задач зарегистрируйте переменную, когда выполняется нормальное выполнение. Затем добавьте условие 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
20
ответ дан 28 November 2019 в 19:27

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

Пример: представьте себе книгу и инвентарь

# 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"

Как запустить только тег 'uninstall' в группе разработчиков

$ ansible- playbook -i inventory site.yml -l dev -s -k -e "uninstall_links = true" -t uninstall

Таким образом, переменные и теги также могут быть в файлах site.yml / inventory, что позволяет выполнять фиксацию в SCM и запишите свое намерение.

0
ответ дан 28 November 2019 в 19:27

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"

0
ответ дан 28 November 2019 в 19:27

Проверка переменной 'tags' не работает в Допустимом 2.1.1.0. См. ниже тест. У меня есть другая идея выполнять задачу только тогда, когда определен тег, работающий как для версии Допустимого 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' в Допустимом 2.1.1.0:

И вот результат:

$ 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   
4
ответ дан 28 November 2019 в 19:27

На 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 , если вы не указываете никаких тегов из ansible-playbook .

Когда вы указываете теги, in_tag остается на True , и запускается задача fail .

PS: вы можете добавить логику к любым задачам вы хотите

PS2: вы также можете расширить логику и жестко закодировать все имеющиеся у вас теги и set_fact: in_tag_blah = True в сочетании с тегами: ["blah"] конечно .

0
ответ дан 28 November 2019 в 19:27

Существует специальный тэг - "никогда" , который предотвращает выполнение задачи, если не запросить специальный тэг.

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]
1
ответ дан 28 November 2019 в 19:27

Возможно, более идиоматичный и элегантный способ - добавить к задаче условие when , например:

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'debug' ]
    when: "'debug' in ansible_run_tags"

Здесь используется магическая переменная ansible_run_tags , который содержит список тегов, предоставленных через аргумент CLI - tags (или синонимично -t ), и имеет эффект выполнения вышеуказанной задачи , если и только если задан тег debug .

Кажется, эта волшебная переменная была введена в ansible 2.5

3
ответ дан 18 February 2020 в 07:18
tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]

Это правильный ответ, но людей часто смущает то, как заставить Ansible добавить этот тег, потому что если вы поместите - tags debug в командную строку, то тогда единственная вещь, которая выполняется, - это задачи отладки. Решение - все теги, отладка , например.

ansible-playbook play.yaml --tags all,debug

В документации Ansible по тегам есть эта строка:

По умолчанию Ansible запускается так, как если бы были указаны --tags all.

0
ответ дан 24 March 2020 в 10:31

Тег never в целом является правильным решением, но в одном случае он не сработает: tags не поддерживаются в мета задачах до Ansible 2.11. В этом случае мы должны подделать поддержку тегов с помощью when: условия и магической переменной ansible_run_tags.

Например, вот фрагмент, в котором будут перечислены все хосты и остановлено воспроизведение досрочно, когда вы скажете --tags list-hosts.Он работает с Ansible 2.8 и выше. Это полезно, если вы создали хосты или группы во время выполнения с помощью add_host или group_by, так как это происходит слишком поздно для --list-hosts.

- pre_tasks:
  - name: List hosts
    assert:
      that: true
      quiet: true
    tags:
      - never
      - list-hosts

  - meta: end_play
    when: "'list-hosts' in ansible_run_tags"
0
ответ дан 10 September 2020 в 05:04

Теги

Похожие вопросы