ansible - 块条件被忽略
ansible - block conditionnal is ignored
我有一个关于 ansible 角色的块的问题
roles/apps_nifi/tasks/main.yml 的摘录:
- debug:
msg: "nifi_extra_instances_name is defined"
when: nifi_extra_instances_name is defined
- debug:
msg: "nifi_extra_instances_name is not defined"
when: nifi_extra_instances_name is not defined
- name: Import variables for extra instances of Nifi
block:
- set_fact:
nifi_extra_instances_vars: "{{ item.value }}"
when: nifi_extra_instances_name in item.key
loop: "{{ lookup('dict', nifi_extra_instances, wantlist=True) }}"
- set_fact:
"{{ item.key }}": "{{ item.value }}"
loop: "{{ lookup('dict', nifi_extra_instances_vars , wantlist=True) }}"
when: nifi_extra_instances_vars is defined and nifi_extra_instances_vars|length > 0
when: nifi_extra_instances_name is defined
nifi_extra_instances_name 是我在需要时调用角色时的变量设置。
手册 main.yml :
- hosts: nifi_hosts
become: yes
roles:
- { role: apps_nifi, tags: nifi }
- { role: apps_nifi-registry, tags: apps_nifi-registry }
- { role: apps_nifi-api, tags: apps_nifi-api, become: no }
#- { role: apps_nifi, tags: "nifi-burn", vars: { nifi_extra_instances_name: burn} }
所以这个例子中没有定义变量nifi_extra_instances_name,我希望进入“block”的代码不会被播放:
TASK [apps_nifi : debug] **********************************************************************************************************************************************
Wednesday 14 October 2020 10:39:45 +0200 (0:00:12.496) 0:00:20.193 *****
skipping: [XXXXX]
TASK [apps_nifi : debug] **********************************************************************************************************************************************
Wednesday 14 October 2020 10:39:45 +0200 (0:00:00.052) 0:00:20.245 *****
ok: [XXXXX] => {
"msg": "nifi_extra_instances_name is not defined"
}
TASK [apps_nifi : set_fact] *******************************************************************************************************************************************
Wednesday 14 October 2020 10:39:45 +0200 (0:00:00.055) 0:00:20.300 *****
skipping: [XXXX] => (item={u'key': u'burn', u'value': {u'nifi_dir': u'/local/nifi-burn', u'nifi_web_https_port': 9445, u'nifi_ports': [u'9445:9445', u'9094:9094'], u'container_name': u'bdmpusher-burn'}})
TASK [apps_nifi : set_fact] *******************************************************************************************************************************************
Wednesday 14 October 2020 10:39:45 +0200 (0:00:00.058) 0:00:20.359 *****
fatal: [XXXXX]: FAILED! => {"msg": "An unhandled exception occurred while running the lookup plugin 'dict'. Error was a <class 'ansible.errors.AnsibleError'>, original message: with_dict expects a dict"}
有什么想法吗?
块的when
条件(以及例如role
节在播放级别,import_task
...)被“推送”到每个受影响的任务。换句话说,在每个任务级别评估完整块的条件。
所以下面这段代码:
- block:
- name: do a
debug:
msg: a
when: task_a_condition
- name: do b
debug:
msg: b
when: task_b_condition
when: block_condition
完全等同于:
- name: do a
debug:
msg: a
when: task_a_condition and block_condition
- name: do b
debug:
msg: b
when: task_b_condition and block condition
因此,所有when条件都是在whatever case中分析的。
此外,在循环时,首先分析loop
表达式以确定所需的迭代次数,然后对每个项目分析when
条件。在您的情况下,它会导致错误,因为 nifi_extra_instances_vars
未定义(因此不是字典)。
您可以在需要时使用以下导致空循环的循环表达式修复该特定任务:
loop: "{{ query('dict', nifi_extra_instances | default({})) }}"
(注意:使用 query
而不是 lookup
自动 returns 一个列表)
现在,如果您真的不希望这些任务即使被跳过也根本不播放,IMO 有一个更好的解决方案:
- 将块任务移动到单独的文件并删除
block
节。
- 使用
include_tasks
,条件与当前区块相同 when
。在这种情况下,它将仅适用于 include 语句本身,而不适用于单个任务。 不要与 import_task
混淆,这会导致与当前问题的块完全相同的结果。
我有一个关于 ansible 角色的块的问题
roles/apps_nifi/tasks/main.yml 的摘录:
- debug:
msg: "nifi_extra_instances_name is defined"
when: nifi_extra_instances_name is defined
- debug:
msg: "nifi_extra_instances_name is not defined"
when: nifi_extra_instances_name is not defined
- name: Import variables for extra instances of Nifi
block:
- set_fact:
nifi_extra_instances_vars: "{{ item.value }}"
when: nifi_extra_instances_name in item.key
loop: "{{ lookup('dict', nifi_extra_instances, wantlist=True) }}"
- set_fact:
"{{ item.key }}": "{{ item.value }}"
loop: "{{ lookup('dict', nifi_extra_instances_vars , wantlist=True) }}"
when: nifi_extra_instances_vars is defined and nifi_extra_instances_vars|length > 0
when: nifi_extra_instances_name is defined
nifi_extra_instances_name 是我在需要时调用角色时的变量设置。
手册 main.yml :
- hosts: nifi_hosts
become: yes
roles:
- { role: apps_nifi, tags: nifi }
- { role: apps_nifi-registry, tags: apps_nifi-registry }
- { role: apps_nifi-api, tags: apps_nifi-api, become: no }
#- { role: apps_nifi, tags: "nifi-burn", vars: { nifi_extra_instances_name: burn} }
所以这个例子中没有定义变量nifi_extra_instances_name,我希望进入“block”的代码不会被播放:
TASK [apps_nifi : debug] **********************************************************************************************************************************************
Wednesday 14 October 2020 10:39:45 +0200 (0:00:12.496) 0:00:20.193 *****
skipping: [XXXXX]
TASK [apps_nifi : debug] **********************************************************************************************************************************************
Wednesday 14 October 2020 10:39:45 +0200 (0:00:00.052) 0:00:20.245 *****
ok: [XXXXX] => {
"msg": "nifi_extra_instances_name is not defined"
}
TASK [apps_nifi : set_fact] *******************************************************************************************************************************************
Wednesday 14 October 2020 10:39:45 +0200 (0:00:00.055) 0:00:20.300 *****
skipping: [XXXX] => (item={u'key': u'burn', u'value': {u'nifi_dir': u'/local/nifi-burn', u'nifi_web_https_port': 9445, u'nifi_ports': [u'9445:9445', u'9094:9094'], u'container_name': u'bdmpusher-burn'}})
TASK [apps_nifi : set_fact] *******************************************************************************************************************************************
Wednesday 14 October 2020 10:39:45 +0200 (0:00:00.058) 0:00:20.359 *****
fatal: [XXXXX]: FAILED! => {"msg": "An unhandled exception occurred while running the lookup plugin 'dict'. Error was a <class 'ansible.errors.AnsibleError'>, original message: with_dict expects a dict"}
有什么想法吗?
块的when
条件(以及例如role
节在播放级别,import_task
...)被“推送”到每个受影响的任务。换句话说,在每个任务级别评估完整块的条件。
所以下面这段代码:
- block:
- name: do a
debug:
msg: a
when: task_a_condition
- name: do b
debug:
msg: b
when: task_b_condition
when: block_condition
完全等同于:
- name: do a
debug:
msg: a
when: task_a_condition and block_condition
- name: do b
debug:
msg: b
when: task_b_condition and block condition
因此,所有when条件都是在whatever case中分析的。
此外,在循环时,首先分析loop
表达式以确定所需的迭代次数,然后对每个项目分析when
条件。在您的情况下,它会导致错误,因为 nifi_extra_instances_vars
未定义(因此不是字典)。
您可以在需要时使用以下导致空循环的循环表达式修复该特定任务:
loop: "{{ query('dict', nifi_extra_instances | default({})) }}"
(注意:使用 query
而不是 lookup
自动 returns 一个列表)
现在,如果您真的不希望这些任务即使被跳过也根本不播放,IMO 有一个更好的解决方案:
- 将块任务移动到单独的文件并删除
block
节。 - 使用
include_tasks
,条件与当前区块相同when
。在这种情况下,它将仅适用于 include 语句本身,而不适用于单个任务。 不要与import_task
混淆,这会导致与当前问题的块完全相同的结果。