Ansible Jinja2模板使用动态变量报错:dict无对应属性
解决Ansible模板中动态引用主机组的变量问题
你遇到的问题核心是Jinja2模板里的变量引用语法错误——你在模板里用了嵌套的"{{ target_hosts }}",导致Ansible把它当成了带引号的字符串字面量,而不是解析成实际的主机组名称。
错误原因分析
当你写groups['"{{ target_hosts }}"']时,Ansible会尝试在groups字典里查找一个名为"my-server-group"(带双引号的完整字符串)的组,但你的实际组名是不带引号的my-server-group,自然找不到对应的键,所以抛出'dict object' has no attribute '"{{ target_hosts }}"'的错误。而用静态组名groups['my-server-group']时,直接匹配到了正确的组,所以能正常运行。
正确的模板写法
只需要直接把target_hosts变量作为groups的索引即可,不需要额外嵌套模板标记和引号:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 {% for item in groups[target_hosts] %} {{ hostvars[item]['ansible_ssh_host'] }} {{ hostvars[item]['openstack']['name'] }} {% endfor %}
如果需要更清晰的变量复用(比如模板里多次用到这个组),也可以先把target_hosts赋值给一个本地模板变量再使用:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 {% set target_group = target_hosts %} {% for item in groups[target_group] %} {{ hostvars[item]['ansible_ssh_host'] }} {{ hostvars[item]['openstack']['name'] }} {% endfor %}
原理说明
在Jinja2的{% ... %}控制块内部,已经处于模板解析上下文,直接写变量名就能被正确解析。嵌套{{ ... }}会让Ansible把变量输出成字符串,而不是作为变量去引用,这就是你之前出错的根本原因。
修改后,Playbook会正确把target_hosts的值(比如my-server-group)代入到groups[]中,遍历对应组的所有主机,生成符合预期的/etc/hosts条目。
内容的提问来源于stack exchange,提问作者shortsteps
相关产品推荐
相关产品推荐

