Ansible在合并列表时意外地将列表转换为字符串,有人可以帮我解释原因吗?
剧本:
---
- hosts: localhost
vars:
list1:
- aaa: 'aaa'
tasks:
- set_fact:
a: 'asdfg'
- set_fact:
list2: "{{ list1|d([]) + [ hostvars['localhost']['a']] }}"
- debug: var=list2
- set_fact:
list3: "{{ list1|d([]) + [ hostvars['localhost']['undefined variable']] }}"
- debug: var=list3
这是播放结果(忽略了不必要的部分):
TASK [debug] *************************************************************************************************************************************************************************************************************************************************
Wednesday 05 September 2018 09:52:31 +0200 (0:00:00.071) 0:00:00.203 ***
ok: [localhost] => {
"list2": [
{
"aaa": "aaa"
},
"asdfg"
]
}
...
TASK [debug] *************************************************************************************************************************************************************************************************************************************************
Wednesday 05 September 2018 09:52:31 +0200 (0:00:00.085) 0:00:00.345 ***
ok: [localhost] => {
"list3": "[{'aaa': 'aaa'}, Undefined]"
}
PLAY RECAP ***************************************************************************************************************************************************************************************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0
第二个调试任务输出字符串而不是预期的dict。这是我不理解的正确行为,还是应该提交错误?
答案 0 :(得分:2)
此答案描述了高达2.6.x的Ansible的状态。 Ansible v2.7中有一个movement支持native Python objects。
Ansible为什么将列表转换为字符串?
Ansible是不在您的示例中将任何列表转换为字符串。
Ansible获取数据:
来自YAML解析器
这些可以是:列表,字典,标量(字符串,布尔值或数字值)。
来自其他来源(例如:Jinja2,清单,CLI Extravars)
任何其他来源的数据都是字符串。
由于Jinja2总是返回字符串,因此您可以在头部计算结果并将值作为YAML引用的标量(由Ansible解释为字符串)传递:
上面的第一个任务等效于:
- set_fact:
list2: "[{'aaa': 'aaa'}, 'asdfg']"
Ansible获取字符串(不是列表)并尝试解释它。它会找到与列表匹配的JSON字符串,并创建一个列表对象。
第二项任务等同于:
- set_fact:
list3: "[{'aaa': 'aaa'}, Undefined]"
您在这里观察到的是Jinja2用带有字符串Undefined
(并且不引用该字符串)的具有未定义值的元素替换列表。
Ansible获取字符串,并尝试对其进行解释。它找不到合适的数据结构 * ,并创建了一个字符串对象。
* 在一种特殊情况下,如果存在一个名为Undefined
的变量,则Ansible将用该变量值替换未引用的Undefined
并创建一个列表对象。>