当变量被命令行中的"-e"覆盖时,Ansible 似乎忽略了条件变量



我正在研究一个使用when条件的Ansible剧本,我试图测试这样的场景,其中有一个默认值指定为一个游戏变量,然后可以使用-e参数从命令行选择性地覆盖到Ansible -playbook。但这并没有像我期望的那样工作,而且我没有看到任何明显的原因。

这里是设置(这是一个超级精简的示例,只是为了说明这一点,而不是我真正的剧本)。

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  

如果我编辑剧本,将注定的变量的值更改为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

并获取"not doomed"消息。我得到的结果是:

$ 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&;像预期的那样。然而,"当"条件语句忽略这个

如果我将命令行改为

也没关系
$ ansible-playbook -e doomed=True conditional_task.yml

在这种情况下,我仍然没有得到条件任务执行。但是,再一次,调试语句显示了注定是存在的,并且其值为&;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上运行的!操作系统:

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

按预期工作。变量注定的类型是布尔值。然后,只需在条件中使用该变量。不需要比较。调试任务将被跳过

shell> ansible-playbook pb.yml
PLAY [localhost] ******************************************************************************
TASK [debug] **********************************************************************************
ok: [localhost] => 
doomed|type_debug: bool
TASK [debug] **********************************************************************************
skipping: [localhost]

当您从命令行传递变量时,事情将发生变化。现在,变量注定的类型是字符串。非空字符串将在条件中求值为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。除此之外,为了简化代码,默认falsetrue,这取决于用例,而不是显式声明。这样可以快速编写代码,并且条件总是按照您的要求执行

shell> cat pb.yml
- hosts: localhost
tasks:
- debug:
msg: We are doomed
when: doomed|d(false)|bool

相关内容

  • 没有找到相关文章