当从命令行用“-e”覆盖时,Ansible 似乎忽略了有条件的变量
Ansible seems to be ignoring variable in when conditional when it is overridden with "-e" from the command line
我正在编写一个使用 when 条件的 Ansible 剧本,我正在尝试测试将默认值指定为播放变量的场景,然后可以使用以下命令从命令行有选择地覆盖该默认值ansible-playbook 的 -e 参数。但这并没有像我预期的那样工作,而且我没有看到任何明显的原因。
这是设置(这是一个超级精简的示例,只是为了说明这一点,而不是我的真实剧本)。
conditional_task.yml
- name: A playbook to conditionally print some debug messages
hosts: localhost
gather_facts: False
vars:
doomed: False
tasks:
- name: print the value of doomed
debug: var=doomed
- name: print the message if we're doomed
debug:
msg: "We're f*****g doomed!"
when: doomed == True
- name: print the message if we're not doomed
debug:
msg: "Glory be to FSM, we are saved!"
when: doomed == False
如果我 运行 使用不带参数的 ansible-playbook 命令,我将得到预期的输出。
$ ansible-playbook conditional_task.yml
PLAY [A playbook to conditionally print some debug messages] ************************************************************************************
TASK [print the value of doomed] ****************************************************************************************************************
ok: [localhost] => {
"doomed": true
}
TASK [print the message if we're doomed] ********************************************************************************************************
ok: [localhost] => {
"msg": "We're f*****g doomed!"
}
TASK [print the message if we're not doomed] ****************************************************************************************************
skipping: [localhost]
PLAY RECAP **************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
如果我编辑 playbook 将注定的 var 的值更改为 False,然后重新运行 这个,我会收到另一条消息。
$ ansible-playbook conditional_task.yml
PLAY [A playbook to conditionally print some debug messages] ************************************************************************************
TASK [print the value of doomed] ****************************************************************************************************************
ok: [localhost] => {
"doomed": false
}
TASK [print the message if we're doomed] ********************************************************************************************************
skipping: [localhost]
TASK [print the message if we're not doomed] ****************************************************************************************************
ok: [localhost] => {
"msg": "Glory be to FSM, we are saved!"
}
PLAY RECAP **************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
现在,鉴于所有这些,我希望能够做这样的事情:
$ ansible-playbook -e doomed=False conditional_task.yml
并收到“未命中”消息。我得到的是:
$ ansible-playbook -e doomed=False conditional_task.yml
PLAY [A playbook to conditionally print some debug messages] ************************************************************************************
TASK [print the value of doomed] ****************************************************************************************************************
ok: [localhost] => {
"doomed": false
}
TASK [print the message if we're doomed] ********************************************************************************************************
skipping: [localhost]
TASK [print the message if we're not doomed] ****************************************************************************************************
skipping: [localhost]
PLAY RECAP **************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
如您所见,在这种情况下, 都不会触发条件。几乎就像变量根本不存在,或者有一些意想不到的值,或者什么的。但正如调试输出所示,变量 已定义 ,并且确实具有预期的值“false”。然而“when”条件语句忽略了这一点。
我把命令行改成
也没关系
$ ansible-playbook -e doomed=True conditional_task.yml
在那种情况下,我仍然没有执行任何条件任务。但同样,调试语句显示 doomed 存在并且值为“true”。
我还尝试将我的条件分别重写为“注定为真”和“注定为假”,而不是使用 == 运算符,这没有任何区别。在这一点上我被卡住了。如果有人能解释一下,将不胜感激。
这是我的 Ansible 版本信息:
$ ansible-playbook --version
ansible-playbook 2.10.8
config file = /extradrive1/development/experimental/ansible/ansible_experimental/ansible.cfg
configured module search path = ['/home/prhodes/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 3.9.7 (default, Sep 10 2021, 14:59:43) [GCC 11.2.0]
这就是 运行Pop 上的全部内容! OS:
NAME="Pop!_OS"
VERSION="21.10"
问题是由于从命令行传递给Ansible的额外变量的类型总是string。例如下面的剧本
shell> cat pb.yml
- hosts: localhost
vars:
doomed: false
tasks:
- debug:
var: doomed|type_debug
- debug:
msg: We are doomed
when: doomed
按预期工作。变量 doomed 的类型是布尔型。然后,只需在条件中使用变量。不需要比较。将跳过调试任务
shell> ansible-playbook pb.yml
PLAY [localhost] ******************************************************************************
TASK [debug] **********************************************************************************
ok: [localhost] =>
doomed|type_debug: bool
TASK [debug] **********************************************************************************
skipping: [localhost]
当您从命令行传递变量时,情况会发生变化。现在,变量 doomed 的类型是一个字符串。 non-empty 字符串在条件中的计算结果为 True,调试任务将被执行
shell> ansible-playbook pb.yml -e doomed=false
PLAY [localhost] ******************************************************************************
TASK [debug] **********************************************************************************
ok: [localhost] =>
doomed|type_debug: str
TASK [debug] **********************************************************************************
ok: [localhost] =>
msg: We are doomed
有一个简单的通用解决方案。 始终将此类变量转换为 bool。除此之外,为了简化代码,default改为false或true,取决于use-case,而是的明确声明。这样你就可以快速编写代码,并且条件将始终按照你的意愿进行
shell> cat pb.yml
- hosts: localhost
tasks:
- debug:
msg: We are doomed
when: doomed|d(false)|bool
我正在编写一个使用 when 条件的 Ansible 剧本,我正在尝试测试将默认值指定为播放变量的场景,然后可以使用以下命令从命令行有选择地覆盖该默认值ansible-playbook 的 -e 参数。但这并没有像我预期的那样工作,而且我没有看到任何明显的原因。
这是设置(这是一个超级精简的示例,只是为了说明这一点,而不是我的真实剧本)。
conditional_task.yml
- name: A playbook to conditionally print some debug messages
hosts: localhost
gather_facts: False
vars:
doomed: False
tasks:
- name: print the value of doomed
debug: var=doomed
- name: print the message if we're doomed
debug:
msg: "We're f*****g doomed!"
when: doomed == True
- name: print the message if we're not doomed
debug:
msg: "Glory be to FSM, we are saved!"
when: doomed == False
如果我 运行 使用不带参数的 ansible-playbook 命令,我将得到预期的输出。
$ ansible-playbook conditional_task.yml
PLAY [A playbook to conditionally print some debug messages] ************************************************************************************
TASK [print the value of doomed] ****************************************************************************************************************
ok: [localhost] => {
"doomed": true
}
TASK [print the message if we're doomed] ********************************************************************************************************
ok: [localhost] => {
"msg": "We're f*****g doomed!"
}
TASK [print the message if we're not doomed] ****************************************************************************************************
skipping: [localhost]
PLAY RECAP **************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
如果我编辑 playbook 将注定的 var 的值更改为 False,然后重新运行 这个,我会收到另一条消息。
$ ansible-playbook conditional_task.yml
PLAY [A playbook to conditionally print some debug messages] ************************************************************************************
TASK [print the value of doomed] ****************************************************************************************************************
ok: [localhost] => {
"doomed": false
}
TASK [print the message if we're doomed] ********************************************************************************************************
skipping: [localhost]
TASK [print the message if we're not doomed] ****************************************************************************************************
ok: [localhost] => {
"msg": "Glory be to FSM, we are saved!"
}
PLAY RECAP **************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
现在,鉴于所有这些,我希望能够做这样的事情:
$ ansible-playbook -e doomed=False conditional_task.yml
并收到“未命中”消息。我得到的是:
$ ansible-playbook -e doomed=False conditional_task.yml
PLAY [A playbook to conditionally print some debug messages] ************************************************************************************
TASK [print the value of doomed] ****************************************************************************************************************
ok: [localhost] => {
"doomed": false
}
TASK [print the message if we're doomed] ********************************************************************************************************
skipping: [localhost]
TASK [print the message if we're not doomed] ****************************************************************************************************
skipping: [localhost]
PLAY RECAP **************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
如您所见,在这种情况下, 都不会触发条件。几乎就像变量根本不存在,或者有一些意想不到的值,或者什么的。但正如调试输出所示,变量 已定义 ,并且确实具有预期的值“false”。然而“when”条件语句忽略了这一点。
我把命令行改成
也没关系$ ansible-playbook -e doomed=True conditional_task.yml
在那种情况下,我仍然没有执行任何条件任务。但同样,调试语句显示 doomed 存在并且值为“true”。
我还尝试将我的条件分别重写为“注定为真”和“注定为假”,而不是使用 == 运算符,这没有任何区别。在这一点上我被卡住了。如果有人能解释一下,将不胜感激。
这是我的 Ansible 版本信息:
$ ansible-playbook --version
ansible-playbook 2.10.8
config file = /extradrive1/development/experimental/ansible/ansible_experimental/ansible.cfg
configured module search path = ['/home/prhodes/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 3.9.7 (default, Sep 10 2021, 14:59:43) [GCC 11.2.0]
这就是 运行Pop 上的全部内容! OS:
NAME="Pop!_OS"
VERSION="21.10"
问题是由于从命令行传递给Ansible的额外变量的类型总是string。例如下面的剧本
shell> cat pb.yml
- hosts: localhost
vars:
doomed: false
tasks:
- debug:
var: doomed|type_debug
- debug:
msg: We are doomed
when: doomed
按预期工作。变量 doomed 的类型是布尔型。然后,只需在条件中使用变量。不需要比较。将跳过调试任务
shell> ansible-playbook pb.yml
PLAY [localhost] ******************************************************************************
TASK [debug] **********************************************************************************
ok: [localhost] =>
doomed|type_debug: bool
TASK [debug] **********************************************************************************
skipping: [localhost]
当您从命令行传递变量时,情况会发生变化。现在,变量 doomed 的类型是一个字符串。 non-empty 字符串在条件中的计算结果为 True,调试任务将被执行
shell> ansible-playbook pb.yml -e doomed=false
PLAY [localhost] ******************************************************************************
TASK [debug] **********************************************************************************
ok: [localhost] =>
doomed|type_debug: str
TASK [debug] **********************************************************************************
ok: [localhost] =>
msg: We are doomed
有一个简单的通用解决方案。 始终将此类变量转换为 bool。除此之外,为了简化代码,default改为false或true,取决于use-case,而是的明确声明。这样你就可以快速编写代码,并且条件将始终按照你的意愿进行
shell> cat pb.yml
- hosts: localhost
tasks:
- debug:
msg: We are doomed
when: doomed|d(false)|bool