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

Ansible 2.4.2.0跨Play访问变量失败排查求助

Ansible跨Play访问注册变量的问题解决办法

嘿,我来帮你搞定这个Ansible跨Play访问变量的问题!你用Ansible 2.4.2.0写的Playbook里,第一个Play在all-compute-host主机上用heat-admin执行hostname命令并注册了变量,第二个Play想在localhost通过hostvars访问这个变量,但一直报变量未定义的错误,试过好几种写法都不行对吧?

先看看你原来的Playbook代码:

$ cat test.yml
- name: Finding Master VMs
  hosts: all-compute-host
  remote_user: heat-admin
  tasks:
    - name: Getting master VM's hostname
      shell: hostname
      register: hostname_output
- name: Access in different play
  hosts: localhost
  connection: local
  tasks:
    - name: Testing vars
      debug: var='{{ hostvars[item]['hostname_output']['stdout'] }}'
      with_items: groups['all-compute-host']

报错信息是这样的:

TASK [Testing vars] *******************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: u\"hostvars['groups['all-compute-host']']\" is undefined\n\nThe error appears to have been in '/tmp/test.yml': line 18, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: Testing vars\n ^ here\n\nexception type: <class 'ansible.errors.AnsibleUndefinedVariable'>\nexception: u\"hostvars['groups['all-compute-host']']\" is undefined"} to retry, use: --limit @/tmp/test.retry

问题出在哪?

仔细看报错信息里的hostvars['groups['all-compute-host']'],这说明Ansible把groups['all-compute-host']当成了一个字符串键,而不是去引用组变量,根本原因有两个:

  1. with_items里的groups['all-compute-host']没有用{{ }}包裹,Ansible不会把它当成变量解析,而是直接作为字符串处理,导致循环时item的值就是groups['all-compute-host'],自然hostvars里没有这个主机。
  2. debug的var参数不需要用{{ }}包裹变量,加了之后反而会引发引号嵌套的解析问题。

正确的解决方案

把第二个Play里的debug任务改成下面这样:

- name: Access in different play
  hosts: localhost
  connection: local
  tasks:
    - name: Testing vars
      debug:
        var: hostvars[item].hostname_output.stdout
      with_items: "{{ groups['all-compute-host'] }}"

或者用方括号的写法也可以,效果一样:

debug:
  var: hostvars[item]['hostname_output']['stdout']

为什么之前的写法都不行?

我来给你逐个分析:

  • debug: var=hostvars[item]['hostname_output']['stdout']:with_items没加{{ }},item还是字符串,无法正确匹配主机。
  • debug: var=hostvars.item.hostname_output.stdout:动态变量名不能用点语法,得用hostvars[item]这种方括号形式才能解析item变量。
  • debug: var=hostvars.all-compute-host.hostname_output.stdout:hostvars的键是单个主机的inventory名称,不是组名,直接用组名访问肯定找不到。
  • debug: var=hostvars['all-compute-host']['hostname_output']['stdout']:同上,组名不能作为hostvars的键,得遍历组里的每个主机。
  • debug: var='hostvars.compute01.hostname_output.stdout':如果compute01是组里的单个主机,这个写法是对的,但只能访问这一台,没法遍历整个组。

修正后的完整Playbook

- name: Finding Master VMs
  hosts: all-compute-host
  remote_user: heat-admin
  tasks:
    - name: Getting master VM's hostname
      shell: hostname
      register: hostname_output

- name: Access in different play
  hosts: localhost
  connection: local
  tasks:
    - name: Testing vars
      debug:
        var: hostvars[item].hostname_output.stdout
      with_items: "{{ groups['all-compute-host'] }}"

这样修改后,Ansible会正确遍历all-compute-host组里的每台主机,然后通过hostvars[item]获取对应主机上注册的hostname_output变量,就能正常输出每台主机的 hostname 了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:35:29