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

如何让Ansible Playbook终端输出解析inventory的ansible_host Jinja变量

解决Ansible Playbook输出中ansible_host Jinja表达式未解析的问题

核心解决方案:修改Inventory变量定义

不需要为每个主机单独定义ansible_host,只需调整inventory中变量的写法即可解决问题:

修改后的Inventory片段

[all:vars]
ansible_connection=network_cli
host_domain=wfm.pvt
ansible_host={{ inventory_hostname }}.{{ host_domain }}

[CEASF]
CEASF-RTR

原理说明

当你用单引号包裹{{ inventory_hostname }}.{{ host_domain }}时,Ansible会将其视为字面字符串,不会触发Jinja表达式解析。去掉单引号后,Ansible在加载inventory阶段就会自动解析该表达式,将ansible_host替换为实际的主机地址(如CEASF-RTR.wfm.pvt),此时playbook的输出就会显示解析后的结果:

changed: [CEASF-RTR -> CEASF-RTR.wfm.pvt] => (item=cowfm-tower-core) => {

替代方案:自定义回调插件(无法修改Inventory时使用)

如果因依赖问题不能修改inventory,可以通过自定义回调插件拦截并修改输出内容,主动解析其中的Jinja表达式。

步骤1:创建回调插件文件

在playbook目录下新建callback_plugins/parse_ansible_host_output.py,内容如下:

from ansible.plugins.callback import CallbackBase

class CallbackModule(CallbackBase):
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'stdout'
    CALLBACK_NAME = 'parse_ansible_host'

    def v2_runner_on_ok(self, result):
        # 获取主机已解析的变量值
        host_vars = result._host.get_vars()
        parsed_ansible_host = host_vars.get('ansible_host')
        
        # 构建解析后的输出前缀
        status = 'changed' if result._result.get('changed') else 'ok'
        host_name = result._host.get_name()
        item_info = f" => (item={result._result['item']})" if result._task_loop else ""
        
        parsed_msg = f"{status}: [{host_name} -> {parsed_ansible_host}]{item_info} => "
        self._display.display(parsed_msg)
        
        # 输出任务结果的详细内容
        self._display.display(self._dump_results(result._result))

    def v2_runner_on_failed(self, result, ignore_errors=False):
        # 对失败任务做同样的解析处理
        host_vars = result._host.get_vars()
        parsed_ansible_host = host_vars.get('ansible_host')
        
        status = 'failed'
        host_name = result._host.get_name()
        item_info = f" => (item={result._result['item']})" if result._task_loop else ""
        
        parsed_msg = f"{status}: [{host_name} -> {parsed_ansible_host}]{item_info} => "
        self._display.display(parsed_msg)
        
        super().v2_runner_on_failed(result, ignore_errors)

步骤2:配置使用回调插件

在ansible.cfg中添加以下配置:

[defaults]
callback_plugins = ./callback_plugins
stdout_callback = parse_ansible_host

或者运行playbook时临时指定:

ansible-playbook -i ce_campus_rtr_inventory_singular your_playbook.yml -e "ansible_callback_plugins=./callback_plugins stdout_callback=parse_ansible_host"

常见疑问解答

  1. 为什么verbose模式和debug模块能看到正确值?

    • Verbose模式的输出来自连接阶段,此时Ansible已经解析了ansible_host变量用于建立连接。
    • Debug模块直接读取的是Ansible内部已解析的主机变量,而非inventory中的原始字符串。
  2. 有没有命令行参数直接实现解析?

    • 没有直接的命令行参数可以强制解析inventory中的Jinja表达式并修改输出,最简便的方式还是修改inventory变量定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 21:54:53