使用jinja2模板时ansible中存在未定义的变量错误

使用jinja2模板时ansible中存在未定义的变量错误,ansible,jinja2,ansible-inventory,ansible-template,Ansible,Jinja2,Ansible Inventory,Ansible Template,我在练习英语。我已经完成了basic,现在我正在构建一个jinja2模板并使用它。当我需要为组构建报告并将其上载到各自的dns服务器时,有一个练习。美国组中所有服务器的报告将上载到dns_服务器_america,亚洲也是如此 dns_server_america ansible_host=172.20.1.100 ansible_ssh_pass=Passw0rd ansible_user=root dns_server_asia ansible_host=172.20.1.101 ansibl

我在练习英语。我已经完成了basic,现在我正在构建一个jinja2模板并使用它。当我需要为组构建报告并将其上载到各自的dns服务器时,有一个练习。美国组中所有服务器的报告将上载到dns_服务器_america,亚洲也是如此

dns_server_america ansible_host=172.20.1.100 ansible_ssh_pass=Passw0rd ansible_user=root
dns_server_asia ansible_host=172.20.1.101 ansible_ssh_pass=Passw0rd ansible_user=root

[america]
web0001 ansible_hostname=web0001.company.com ansible_host=10.1.1.101 
web0002 ansible_hostname=web0002.company.com ansible_host=10.1.1.102 


[asia]
web2001 ansible_hostname=web2001.company.com ansible_host=10.1.1.201 
web2002 ansible_hostname=web2002.company.com ansible_host=10.1.1.202 
这是YAML

- name: Generate dns hosts files on americas servers
  hosts: dns_server_america
  tasks:
  - template: src=templates/hosts.j2 dest=/tmp/hosts.txt
    vars:
      GROUP_NAME: america

- name: Generate dns hosts files on asia servers
  hosts: dns_server_asia
  tasks:
  - template: src=templates/hosts.j2 dest=/tmp/hosts.txt
    vars:
      GROUP_NAME: asia
这是jinja2模板

{% for host in groups[GROUP_NAME] %}
{{ host }} {{ hostvars[host]['ansible_host'] }}
{% endfor %}
为什么我们不在jinja2模板中引用[host][GROUP\u NAME]。Ansible说,当变量放在方括号中时,应该用引号括起来。当我用引号括起来时,我会收到一条错误消息“undefined variable”,当我删除引号时,我就能够成功地运行playbook了。请告知,我可能遗漏了一些东西,或者我理解变量的理论可能是错误的

问:“为什么我们不在jinja2模板中引用[host]和[GROUP_NAME]?”

答:主机名和组名都是变量。索引中需要变量的值。如果变量名称被引用为“主机”或“组名称”,则使用变量名称而不是变量值


直接和间接的

例如,模板

shell>cat test.txt.j2
{{dict[index]}
{{dict['index']}
还有剧本

shell>cat playbook.yml
-主机:本地主机
变量:
格言:
索引:属性索引的值
attr1:属性attr1的值
任务:
-模板:
src:test.txt.j2
dest:test.txt
变量:
索引:attr1
给予

shell>cat test.txt
属性attr1的值
属性索引值

这不限于模板。它通常是有效的。比如说

-调试:
味精:
-“{{dict[index]}”
-“{{dict['index']}”
变量:
索引:attr1
给予

msg:
-属性attr1的值
-属性索引值

虚线

可以使用“虚线”引用。比如说

-调试:
变量:目录索引
给予

dict.index:属性索引的值
“虚线”引用可以在嵌套字典中使用。例如,使用嵌套字典

dict:
索引:
var1:属性索引的值
属性1:
var1:属性attr1的值
两个版本都按预期工作

    - debug:
        msg:
          - "{{ dict.index.var1 }}"
          - "{{ dict['index'].var1 }}"
      vars:
        index: attr1
给予

msg:
-属性索引值
-属性索引值

模板中的虚线引用

但使用模板时会有区别。将引用放入括号中时,
[]
所有后续引用也必须放入括号中。否则,模板将失败。比如说

shell>cat test.txt.j2
{{dict.index.var1}}好的
{{dict.index['var1']}}#好的
{{dict['index']['var1']}}好的
{{dict['index'].var1}}错误:没有属性var1
将失败

fatal: [localhost]: FAILED! => changed=false 
  msg: 'AnsibleUndefinedVariable:
        ''ansible.parsing.yaml.objects.AnsibleUnicode object''
        has no attribute ''var1'''

理解。但我无法用正确的语言将它们回复给你们,以验证我的理解。谢谢你的简短解释,