Ansible标签只能用于运行任务/角色的子集。这意味着默认情况下,所有任务都将执行,并且我们只能阻止某些任务执行。我们可以在任务的when部分中使用当前标签吗?

评论

听起来您需要的是一些任务设置,例如limit_to_tags:foo,该设置不存在,我认为目前无法实现。未来的实现还需要制定一个计划,以将这些标记进行AND或OR运算。

在“ Ansible-默认/显式标签”stackoverflow.com/questions/28789912/…中查看我的答案。

#1 楼

Ansible 2.5带有特殊标签neveralways。标签never可以完全用于此目的。例如:

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


在此示例中,仅当显式请求debug(或never)标记时,任务才会运行。 [有关Ansible文档的参考]

#2 楼

尽管这是一种环岛解决方案,但它可以工作。然后,将检查该变量的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


评论


您也可以使用untagged完成此操作:-set_fact:untagged_run = true标签:untagged

– Pyzo
17年11月28日在19:56

您能解释一下吗?一个真实的例子?

– Quintin Par
18年7月10日在1:18

#3 楼

我没有足够的声誉来赞扬或评论建议使用命令行变量(--extra-vars)的答案,但是我要补充一点:


警告如果您未定义该额外变量,则此方法将导致播放错误并失败。


您可以在没有--extra-vars定义的情况下通过在默认值中定义默认值来防止播放失败剧本本身:

---
- 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时,播放运行没有错误。

评论


使用彻底|可以实现相同的效果。 default('no')|布尔

– Costi Ciudatu
2015年10月10日17:09

或在以下情况下:彻底定义,如果您喜欢该语法,则考虑彻底

– KCD
17年4月19日在18:57

谢谢,爱的定义和语法更多。不仅仅是我不觉得很直观的多个管道。

–伊利亚·林恩(Elijah Lynn)
17年12月22日在22:49

#4 楼

您可以使用条件语句来防止意外运行的任务,如果您未指定标签,这些任务将被执行。此方法的警告是,如果您未定义该额外变量,则播放将出错并失败。

使用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)
...


评论


如果您未定义“彻底”,为避免错误,只需使用彻底| default(“ false”)| match(“ true”)。默认值不必为false,也可以不等于true,但是可以提高可读性。

–汤姆·威尔逊
16/12/22在14:37

#5 楼

是。运行带有--tags foo标志的ansible-playbook将确保仅执行带有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节中使用标签来有条件地执行任务。
请注意,这取决于您的剧本的复杂性/ roles,您可能需要结合使用--tags和--skip-tags来控制执行哪些任务。例如,如果一个include任务标记为'foo',而包含的剧本中的某个任务标记为'bar',则您运行

ansible-playbook --tags "foo"


内部任务(仅标记为“ bar”)。为避免执行所有标记为“ bar”的内部任务,您将必须执行以下命令

ansible-playbook --tags foo --skip-tags bar


评论


事实并非如此:“在任务上指定标签意味着仅当将该标签显式传递到ansible-playbook命令时,该任务才会执行。”

–金博兰
14-10-22在8:25



其次,声明不正确。

–克里斯
2014年11月20日19:26

是的,您可以通过确保始终使用正确的ansible-playbook选项来实现此行为,但是我认为OP正在要求一种注释任务的方法,以便除非在ansible中显式添加了特定标签,否则该任务不会执行-playbook命令。

– dgh
2015年1月4日,0:41



是的,这不能回答OP的问题。

–艾伦·卢斯(Allen Luce)
15年5月29日在17:23

当您未指定标签时,所有带标签/未带标签的操作都会运行。标签不能排除要运行的动作,只能包括。除加法过滤器外,没有谓词逻辑。

– bbaassssiiee
16-09-22在5:59

#6 楼

在Ansible 2.1.1.0中,无法检查“ tags”变量。测试请参见下文。
我还有另一种想法,即仅在定义了标签且对Ansible 1.9.X和2.XY都起作用的情况下才执行任务:

- 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


因此,在运行没有任何标签的剧本时,'foo'变量将设置为true,然后设置为false,因此不会执行任何操作。如果添加'bar'标签,则仅应用第一个设置,因此'foo'变量为true,则将执行任务。享受吧!


这里是有关Ansible 2.1.1.0中'tags'变量的测试:

这是剧本:

- 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   


评论


有变量ansible_run_tags(在docs.ansible.com/ansible/latest/reference_appendices/…中找到)。这应该对变量“ tags”起作用。

– simohe
20-10-1在11:59

#7 楼

有一个特殊的标记-“从不”,除非有特殊要求,否则它将阻止任务运行。

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


评论


上面的答案中已经提到:serverfault.com/a/907329/105928

–塔哈·贾汉吉尔(Taha Jahangir)
18年6月9日在4:58

#8 楼

也许更惯用和优雅的方法是在任务中添加一个when条件,例如:通过CLI参数ansible_run_tags(或同义--tags),并且只有在给定标签-t的情况下,才具有运行上述任务的效果。 />

#9 楼

when子句无法评估标签的存在。作为一种解决方法,我将变量和标签一起使用以运行特定于该标签/变量的任务。

例如:想象一个剧本和库存

/>使用这种方法,您可以使用标记仅选择uninstall.yml中的任务,但是还需要将“ uninstall_links”变量设置为启用该变量的功能。因此,如果您不带任何参数运行剧本,则默认情况下它将运行安装任务。要卸载,您可以将标签“ uninstall”设置为您的剧本(或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 /库存文件中,从而使您能够提交到SCM中并记录您的意图。

#10 楼

nootal是正确的,我的方法行不通-忽略它:(
我现在使用“ when:myvar已定义”,并且命令行开关“ -e” myvar = X”仅在显式请求时执行任务。 br />
更容易(至少在ansible 2.1.1.0中使用):

- name: do something only when tag 'foo' is provided
  when: tags is defined
  tags: foo


->仅在提供了标签且标签包含“ foo“

#11 楼

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 t从tags中指定任何ansible-playbook

指定标签时,in_tag停留在True处,并且fail任务运行。

PS:您可以将逻辑添加到您要执行的任何任务中想要

PS2:您还可以扩展逻辑并对所有标签和set_fact: in_tag_blah=True进行硬编码,当然还要结合tags: ["blah"]

#12 楼

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


这是正确的答案,但经常使人们感到困惑的是如何使Ansible添加此标记,因为如果将--tags debug放在命令行上,那么唯一运行的就是调试任务。解决方案是--tags all,debug例如,

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


标签上的Ansible文档具有以下行:


默认情况下,Ansible就像--tags已经全部指定。


#13 楼

通常,never标签是正确的解决方案,但在一种情况下将不起作用:直到Ansible 2.11,meta任务才支持标签。在这种情况下,我们必须使用条件变量when:和魔术变量ansible_run_tags来伪造标签支持。
例如,以下代码段将列出所有主机,并在您说--tags list-hosts时尽早结束播放。它适用于Ansible 2.8及更高版本。如果您在运行时使用add_hostgroup_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"