You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Ansible Jinja模板中无法获取动态/其他主机的变量

Ansible模板hostvars引用语法错误解决

问题场景

通过变量final_delegate根据用户传入的perform_action参数决定Play2的目标主机,在生成HTML模板时引用hostvars出现语法错误。

相关Playbook代码

- name: "Play 1"
  hosts: localhost
  tasks:
   - set_fact:
       final_delegate: "{{ 'localhost' if perform_action in 'telnetcurlnslookuptracerouteget_ip_address' else 'dest_nodes' }}"

- name: "Play 2"
  hosts: "{{ hostvars.localhost.final_delegate }}"
  tasks:
   - name: Run command
     ignore_errors: yes
     command:  ls -ltr /tmp/all.pdf
     register: cmdoutput

   - name: Creating body template
     template:
       src: "{{ playbook_dir }}/body.html.j2"
       dest: "{{ playbook_dir }}/body.html.tmp"
     delegate_to: localhost

错误的模板代码(body.html.j2)

<tr>
    <td>{{ inventory_hostname }}</td>
    <td><pre>{{ hostvars.[inventory_hostname].cmdoutput.stdout_lines | join('\n') }}</pre></td>
  </tr>

报错信息

An exception occurred during task execution. To see the full traceback, use -vvv. The error was:   </tr>
fatal: [localhost]: FAILED! => {"changed": false, "msg": "AnsibleError: template error while templating string: expected name or number. String:  <tr>\n    <td>{{ inventory_hostname }}</td>\n    <td><pre>{{ hostvars.[inventory_hostname].cmdoutput.stdout_lines | join('\\n') }}</pre></td>\n    </tr>\n\n"}

尝试过的错误写法

1.
    <td><pre>{{ hostvars.[hostvars.localhost.final_delegate].cmdoutput.stdout_lines | join('\n') }}</pre></td>
2.
    <td><pre>{{ hostvars.['hostvars.localhost.final_delegate'].cmdoutput.stdout_lines | join('\n') }}</pre></td>

错误原因

核心问题是hostvars的变量引用语法错误:

  • Ansible中,若通过变量动态获取hostvars中的主机条目,必须使用hostvars[变量名]的方括号语法;
  • 点语法(如hostvars.localhost)仅适用于已知的固定主机名,不能在点后紧跟方括号(如hostvars.[变量名]),这属于语法违规。

正确写法建议

写法一:通过inventory_hostname动态获取(适用于Play2目标为单主机)

Play2的hosts参数是final_delegate,模板执行时inventory_hostname即为目标主机名,直接用方括号语法引用:

<tr>
    <td>{{ inventory_hostname }}</td>
    <td><pre>{{ hostvars[inventory_hostname].cmdoutput.stdout_lines | join('\n') }}</pre></td>
</tr>

写法二:直接引用final_delegate对应的主机

若需明确指定final_delegate变量对应的主机,同样使用方括号语法解析变量:

<tr>
    <td>{{ hostvars.localhost.final_delegate }}</td>
    <td><pre>{{ hostvars[hostvars.localhost.final_delegate].cmdoutput.stdout_lines | join('\n') }}</pre></td>
</tr>

注意事项

  • 若final_delegate是主机组(如dest_nodes),需遍历组内主机来获取每个主机的cmdoutput,可使用loop或with_items遍历groups[hostvars.localhost.final_delegate];
  • 确保cmdoutput变量已在目标主机的hostvars中存在(即Play2的Run command任务已成功执行)。

内容的提问来源于stack exchange,提问作者Ashar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 19:20:16