Ansible 究竟如何解析布尔变量?

How Exactly Does Ansible Parse Boolean Variables?

在 Ansible 中,有几个地方可以定义变量:在 inventory 中,在 playbook 中,在变量文件中,等等。谁能解释一下我所做的以下观察?

  1. 在清单中定义布尔变量时,它必须大写(即 True/False),否则(即 true/false)它不会被解释为布尔值而是字符串.
  2. 在任何 YAML 格式的文件(剧本、角色等)中,True/False 和 true/false 都被解释为布尔值。

比如我在一个清单中定义了两个变量:

abc=false
xyz=False

并且在调试角色内这些变量的类型时...

- debug:
    msg: "abc={{ abc | type_debug }}  xyz={{ xyz | type_debug }}"

... 然后 abc 变为 unicodexyz 被解释为 bool:

ok: [localhost] => {
    "msg": "abc=unicode  xyz=bool"
}

但是,在 playbook 中定义相同的变量时,如下所示:

  vars:
    abc: false
    xyz: False

... 那么两个变量都被识别为 bool.

在生产环境中执行剧本后,我不得不以艰难的方式意识到这一点,运行宁一些不应该 运行 因为变量设置为 'false' 而不是 'False'在库存中。因此,我真的很想找到一个明确的答案,说明 Ansible 如何理解布尔值以及它如何依赖于 where/how 定义的变量。为了安全起见,我应该总是使用大写的 True/False 吗? YAML 文件(格式 key: value)中的布尔值不区分大小写,而属性文件(格式 key=value)中的布尔值区分大小写是否有效?任何更深入的见解将不胜感激。

YAML 文件中定义的变量(剧本、vars_files、YAML 格式清单)


YAML 原则

剧本、vars_files 和 首先由 YAML 解析器处理。它允许将存储为 Boolean 类型的值的多个别名:yes/notrue/falseon/off,在几种情况下定义:true/True/TRUE(因此它们并非真正不区分大小写)。

YAML definition 将可能的值指定为:

y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF

Ansible docs confirm that:

You can also specify a boolean value (true/false) in several forms:

create_key: yes
needs_agent: no
knows_oop: True
likes_emacs: TRUE
uses_cvs: false


INI 格式清单文件中定义的变量


Python原则

当 Ansible 读取 INI 格式的清单时,它会处理变量 using Python built-in types:

Values passed in using the key=value syntax are interpreted as Python literal structure (strings, numbers, tuples, lists, dicts, booleans, None), alternatively as string. For example var=FALSE would create a string equal to FALSE.

如果指定的值匹配字符串 TrueFalse(以大写字母开头),则类型设置为布尔值,否则将其视为字符串(除非它匹配另一种类型)。



通过 --extra_vars CLI 参数定义的变量


所有字符串

在 CLI 中作为额外变量传递的所有变量都是字符串类型。

YAML 原则定义了 Ansible 接受的可能的布尔值。然而,在解析后只剩下两个值(true 和 false),它们在 JSON 中也是有效的,所以如果你用 JSON in Ansible 做事,那么 truefalse 是不错的选择。最好的恕我直言。

#!/usr/bin/env ansible-playbook
---

- name: true or false?
  hosts: all
  gather_facts: false

  tasks:

    - name: "all these boolean inputs evaluate to 'true'"
      debug:
        msg: "{{ item }}"
      with_items:
        - true
        - True
        - TRUE
        - yes
        - Yes
        - YES
        - on
        - On
        - ON

    - name: "all these boolean inputs evaluate to 'false'"
      debug:
        msg: "{{ item }}"
      with_items:
        - false
        - False
        - FALSE
        - no
        - No
        - NO
        - off
        - Off
        - OFF

YAML 原则定义了 Ansible 接受的可能的布尔值。但是在解析后只剩下两个值(true 和 false),它们在 JSON 中也是有效的,所以如果你用这些值 Ansible 中做一些事情,那么 truefalse 是不错的选择。还有 Ansible documentation 状态

Use lowercase ‘true’ or ‘false’ for boolean values in dictionaries if you want to be compatible with default yamllint options.

#!/usr/bin/env ansible-playbook
---

- name: true or false?
  hosts: all
  gather_facts: false

  tasks:

    - name: "all these boolean inputs evaluate to 'true'"
      debug:
        msg: "{{ item }}"
      with_items:
        - true
        - True
        - TRUE
        - yes
        - Yes
        - YES
        - on
        - On
        - ON

    - name: "all these boolean inputs evaluate to 'false'"
      debug:
        msg: "{{ item }}"
      with_items:
        - false
        - False
        - FALSE
        - no
        - No
        - NO
        - off
        - Off
        - OFF