Ansible:仅在指定标签时才执行任务

Ansible标签可以用来只运行任务/angular色的一个子集。 这意味着默认情况下所有的任务都被执行,我们只能阻止一些任务的执行。

我们是否可以限制只有在指定了“foo”标签时才能执行的任务? 我们可以在任务部分使用当前标签吗?

    虽然这是一个迂回的解决scheme,它的工作原理。

    在正常执行运行时,在任务列表内部注册一个variables。 然后,添加一个when条件,将该variables检查到标记的任务。

     - 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 

    我没有足够的声望来赞扬或评论build议使用命令行variables( --extra-vars )的答案,但我有这个补充:

    对这种方法的警告是,如果你没有定义这个额外的variables,那么这个游戏就会失败并失败。

    您可以通过在剧本本身中定义一个默认值来避免在缺less--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覆盖仍然可以工作,因为在命令行中定义的variables优先于所有其他定义。

    结果是,当命令行中的thorough更改为true时,播放没有错误thorough运行。

    您可以使用条件来防止意外运行的任务,否则,如果您不指定标记,将会执行这些任务。 对这种方法的警告是,如果你没有定义这个额外的variables,那么这个游戏就会失败并失败。

    使用extra-vars参数可以触发你的条件被执行。

    从可靠的剧本 – 帮助:

      -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 | match("true") ... 

    是。 使用--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任务被执行。

    所以实际上你并不需要在部分中使用标签来有条件地执行任务。 请注意,根据您的剧本/angular色的复杂性,您可能需要使用–tags和–skip-tags的组合来控制执行哪些任务。 例如,如果包含任务被标记为“foo”,并且包含的​​Playbook中的某个任务被标记为“bar”,并且您运行

     ansible-playbook --tags "foo" 

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

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

    检查'tags'variables在Ansible 2.1.1.0中不起作用。 见下面的testing。 我有一个其他的想法,只有当定义标签时,才能执行任务,同时适用于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'variables将被设置为true,然后被设置为false,所以不执行任何操作。 如果添加“bar”标签,则只会应用第一个设置,所以“foo”variables将为true,那么您的任务将被执行。 请享用!


    这里是关于Ansible 2.1.1.0中的'tags'variables的testing:

    这是剧本:

     - 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 

    when子句不能评估标签的存在。 作为解决方法,我使用variables和标签一起运行特定于该标签/variables的任务。

    例如:想像一下剧本和库存

     #库存
     [dev的]
     192.168.1.1
    
     #site.yml
     - 主机:开发
      angular色:
         -  {role:common}
    
    和common / tasks / main.yml
    
     #roles / common / tasks / main.yaml
     - 名称:安装链接
       apt:name = links state = present
    
     - 包括:uninstall.yml
      何时:uninstall_links被定义
      标签:
         - 卸载
    
     #roles / common / tasks / uninstall.yml
     - 名称:卸载链接
       apt:name = links state = absent
    

    通过这种方法,您可以使用标签来仅selectuninstall.yml中的任务,但是您还需要设置“uninstall_links”variables以启用它。 所以如果你运行没有任何参数的剧本,默认情况下会运行安装任务。 要卸载,您可以将标记“卸载”设置为您的playbook(或cmdline),并且必须设置variables。 如果你没有设置标签,它将按顺序运行一切(安装和卸载),这对testing整个过程是很好的。

    如何运行一切(将安装和卸载):

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

    如何只运行dev组上的'uninstall'标签

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

    因此,variables和标签也可以在site.yml / inventory文件中,允许你提交到你的SCM并logging你的意图。

    nootal是正确的,我的方法是行不通的 – 忽略它:(我现在使用“when:myvar is defined”和命令行开关“-e”myvar = X“只有在明确请求时才执行任务。

    更容易(至less用2.1.1.0):

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

    – >只有在提供标签时才会执行AND标签包含“foo”

    Ansible 2.3.2.0 ,这是我对这个问题的解决scheme:

     --- - 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然后在没有指定任何tagsset_fact ,将set_fact设置为False

    当您指定标签时, in_tag保持为True并运行fail任务。

    PS:你可以把逻辑添加到你想要的任何任务

    PS2:你也可以扩展逻辑和硬编码你所有的标签和set_fact: in_tag_blah=True结合tags: ["blah"]当然。