我正在尝试创建字典。使用var时,一切正常。但是Set_fact就像是被忽略的东西,我无法隔离。
阅读Jinja2手册,多次迭代
---
- hosts: localbox gather_facts: false
vars:
app_servers: 5
ipaddress_base: "192.168.0"
rmi_portbase: 10000
host_info: |
{% set res = [] -%}
{%- for number in range(1,app_servers + 1) -%}
{% set ignored = res.extend([{
'hostname': 'app' + number|string,
'ipaddress': ipaddress_base + '.' + number|string,
'rmi_port': rmi_portbase|int + ( number * 10)
}]) -%}
{%- endfor %}
{{ res }}
tasks:
- name: thing
set_fact:
thing2: "{% set res = [] -%}
{%- for number in range(1,app_servers + 1) -%}
{% set ignored = res.extend([{
'hostname': 'app' + number|string,
'ipaddress': ipaddress_baase + '.' + number|string,
'rmi_port': rmi_portbase|int + ( number * 10)
}]) -%}
{%- endfor %}
{{ res }}"
- debug: var=host_info[0].hostname
- debug: var=thing2[0]
我希望来自Thing2的结果类似于host_info。
TASK [debug] *******************************************************************
ok: [localhost] => {
"host_info[0].hostname": "app1"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"thing2[0]": " "
}
答案 0 :(得分:1)
如果您运行发布的剧本,它将失败并显示以下错误:
任务[事物]
致命:[localhost]:失败! => {“ msg”:“该任务包括一个选项 具有未定义的变量。错误是:“ ipaddress_baase”为 未定义\ n \ n错误似乎出在'/ home / lars / tmp / ansible / playbook.yml':第25行第7列,但可能\在 文件,具体取决于确切的语法问题。\ n \ n违规行 似乎是:\ n \ n \ n-名称:thing \ n ^她的e \ n“}
确实,您将ipaddress_base
拼写为ipaddress_baase
(请注意额外的a
)。如果您修正了该错字并添加,请修改最终的debug
任务,如下所示:
- debug: var=thing2
您应该看到以下输出:
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"thing2": " [{'rmi_port': 10010, 'hostname': u'app1', 'ipaddress': u'192.168.0.1'}, {'rmi_port': 10020, 'hostname': u'app2', 'ipaddress': u'192.168.0.2'}, {'rmi_port': 10030, 'hostname': u'app3', 'ipaddress': u'192.168.0.3'}, {'rmi_port': 10040, 'hostname': u'app4', 'ipaddress': u'192.168.0.4'}, {'rmi_port': 10050, 'hostname': u'app5', 'ipaddress': u'192.168.0.5'}]"
}
向我们显示的是thing2
是字符串,而不是字典。因此,当您为thing2[0]
分配任务时,您将在该字符串的位置0
处获得字符。
原因是一个字符串,而不是字典是因为是索引0处的前导空格。我们可以通过更改{{1 }}语句从endfor
到%}
,它将占用以下任何空白:
-%}
完成此任务和您最初的- set_fact:
thing2: "{% set res = [] -%}
{%- for number in range(1,app_servers + 1) -%}
{% set ignored = res.extend([{
'hostname': 'app' + number|string,
'ipaddress': ipaddress_baase + '.' + number|string,
'rmi_port': rmi_portbase|int + ( number * 10)
}]) -%}
{%- endfor -%}
{{ res }}"
任务,我们将其视为输出:
debug
话虽如此,我将停止尝试使用这种技术来生成复杂的数据结构,因为正如我们所看到的那样,它容易出错。我会这样写:
TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost]
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"host_info[0].hostname": "app1"
}
TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"thing2[0]": {
"hostname": "app1",
"ipaddress": "192.168.0.1",
"rmi_port": 10010
}
}
我认为这既易于实现,又易于阅读。