在合并列表时,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。这是一个我不理解的正确行为还是应该提交错误?
这个答案描述了Ansible中的事物状态,最高可达2.6.x.在Ansible v2.7中有一个movement支持native Python objects。
为什么Ansible将列表转换为字符串?
Ansible不会将任何列表转换为示例中的字符串。
Ansible获取数据:
由于Jinja2总是返回一个字符串,你可以计算头部的结果并将值作为YAML引用的标量传递(由Ansible解释为字符串):
- set_fact:
list2: "[{'aaa': 'aaa'}, 'asdfg']"
Ansible获取一个字符串(不是列表)并尝试解释它。它找到一个匹配列表的JSON字符串并创建一个列表对象。- set_fact:
list3: "[{'aaa': 'aaa'}, Undefined]"
你在这里观察的是Jinja2用一个带有未定义值的元素替换一个列表,其中包含一个字符串Undefined
(而不是引用该字符串)。
Ansible获取一个字符串并尝试解释它。它找不到合适的数据结构*并创建一个字符串对象。*有一种特殊情况,如果存在一个名为Undefined
的变量,则Ansible将用该变量值替换未加引号的Undefined
并创建一个列表对象。