Ansible标签只能用于运行任务/角色的子集。这意味着默认情况下将执行所有任务,并且我们只能阻止某些任务执行。
是否可以仅在指定了“ foo”标签的情况下将任务限制为可以执行?我们可以在when
任务部分使用当前标签吗?
Ansible标签只能用于运行任务/角色的子集。这意味着默认情况下将执行所有任务,并且我们只能阻止某些任务执行。
是否可以仅在指定了“ foo”标签的情况下将任务限制为可以执行?我们可以在when
任务部分使用当前标签吗?
Answers:
Ansible 2.5带有特殊标签never
和always
。标签never
可以完全用于此目的。例如:
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'never', 'debug' ]
在此示例中,仅在显式请求debug
(或never
)标签时任务才会运行。[有关Ansible文档的参考]
尽管这是一种回旋解决方案,但它可以工作。
当正常执行运行时,在任务列表中注册一个变量。然后,将检查该变量的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
tags: untagged
我没有足够的声誉来赞扬或评论建议使用命令行变量(--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
因为在命令行上定义的变量优先于所有其他定义,所以覆盖via 仍将起作用。
结果是,当thorough
未true
在命令行上更改为时,播放将正确运行。
thorough | default('no') | bool
。
when: thorough is defined and thorough
如果您更喜欢该语法
is defined and
更喜欢语法。不仅仅是我不觉得很直观的多个管道。
您可以使用条件语句来防止意外运行的任务,如果您未指定标签,这些任务将被执行。该方法的警告是,如果您未定义该额外变量,则播放将出错并失败。
使用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)
...
thorough | default("false") | match("true")
。默认值不必是false
,只要不匹配即可true
,但是它提高了可读性。
在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
是。使用该--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节中使用标签来有条件地执行任务。请注意,根据您的剧本/角色的复杂程度,您可能需要使用--tags和--skip-tags的组合来控制执行哪些任务。例如,如果包含任务标记为“ foo”,而包含的剧本中的某些任务标记为“ bar”,则您运行
ansible-playbook --tags "foo"
内部任务(仅标记为“ bar”)将被执行。为了避免执行所有标记为“ bar”的内部任务,您将必须执行以下命令
ansible-playbook --tags foo --skip-tags bar
ansible-playbook
选项来实现此行为,但是我认为OP正在要求一种对任务进行注释的方法,以便除非在ansible-playbook
命令中显式添加了特定标记,否则该任务就不会执行。
有一个特殊的标记- “ never”,除非特别要求标记,否则它将阻止任务运行。
tasks:
- debug: msg='{{ showmevar}}'
tags: [ 'never', 'debug' ]
when子句无法评估标签的存在。作为一种解决方法,我将变量和标签一起使用以运行特定于该标签/变量的任务。
例如:想像一下剧本和广告资源
#库存 [开发] 192.168.1.1 #site.yml -主持人:dev 角色: -{角色:普通} 并在common / tasks / main.yml中 #角色/通用/任务/main.yaml -名称:安装链接 apt:名称=链接状态=存在 -包括:uninstall.yml 时间:定义了uninstall_links 标签: - 卸载 #角色/普通/任务/uninstall.yml -名称:卸载链接 apt:名称=链接状态=不存在
通过这种方法,您可以使用标记仅选择uninstall.yml中的任务,但是还需要将“ uninstall_links”变量设置为某种变量以启用它。因此,如果您在没有任何参数的情况下运行剧本,则默认情况下,它将运行安装任务。要卸载,您可以将标签“ uninstall”设置为您的剧本(或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中并记录您的意图。
在上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
然后在没有指定from 时set_fact
将其重新设置为False
on 。tags
ansible-playbook
当您指定标签时,将in_tag
停留在True
并且fail
任务运行。
PS:您可以将逻辑添加到所需的任何任务中
PS2:您当然也可以set_fact: in_tag_blah=True
结合使用tags: ["blah"]
,扩展逻辑并对所有标签进行硬编码。