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

使用ansible_host调用hostvars值时循环列表失败问题求助

Ansible循环中'ansible_host'未定义错误的解决方法

问题场景

基于inventory中主机的environment变量生成NFS挂载路径时,前两个debug任务能正确显示变量值,但遍历nfs_mounts的循环任务报错'ansible_host' is undefined,导致挂载任务无法执行。

相关文件

Inventory文件

[Hosts]
host1 environment=dev
hots2 environment=test

原Playbook代码(deploy.yml)

---
- name: Mount issue
  hosts: all
  gather_facts: false
  vars:
    nfs_hostname: server1
    nfs_mounts:
      - { src: "/mnt/nas/{{ hostvars[ansible_host].environment }}/drive1", dest: /mnt/drive1 }
      - { src: "/mnt/nas/{{ hostvars[ansible_host].environment }}/drive2", dest: /mnt/drive2 }
  tasks:
    - name: display environments
      debug:
        var: hostvars[ansible_host].environment
    - name: display mounts
      debug:
        var: nfs_mounts
    - name: display each mount
      debug:
        var: item
      with_items:
        - "{{ nfs_mounts }}"
    - name: mount
      mount:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
      with_items:
        - "{{ nfs_mounts }}"

执行错误信息

TASK [display each mount] **************************************************************************************************
fatal: [host1]: FAILED! => {"msg": "[{'src': '/mnt/nas/{{ hostvars[ansible_host].environment }}/drive1', 'dest': '/mnt/drive1'}, {'src': '/mnt/nas/{{ hostvars[ansible_host].environment }}/drive2', 'dest': '/mnt/drive2'}]: 'ansible_host' is undefined"}
fatal: [hots2]: FAILED! => {"msg": "[{'src': '/mnt/nas/{{ hostvars[ansible_host].environment }}/drive1', 'dest': '/mnt/drive1'}, {'src': '/mnt/nas/{{ hostvars[ansible_host].environment }}/drive2', 'dest': '/mnt/drive2'}]: 'ansible_host' is undefined"}

问题原因

在Play的vars块中定义nfs_mounts时,变量内的模板语法{{ hostvars[ansible_host].environment }}虽在单个debug任务中能被正确渲染,但通过with_items引用变量时,Ansible会重新解析变量的原始定义,此时循环上下文无法获取ansible_host变量,导致模板渲染失败。

本质是Play级别的vars在加载阶段解析,任务级别的循环引用触发二次解析时,主机相关变量的作用域丢失。

解决方案

将nfs_mounts的定义从Play的vars块移到set_fact任务中,让每个主机在执行任务时动态生成符合自身环境的挂载配置,确保变量被正确渲染且在后续任务中保持正确状态。

修改后的Playbook代码:

---
- name: Mount issue
  hosts: all
  gather_facts: false
  vars:
    nfs_hostname: server1
  tasks:
    - name: display environments
      debug:
        var: hostvars[ansible_host].environment

    - name: Define NFS mounts for current host
      set_fact:
        nfs_mounts:
          - { src: "/mnt/nas/{{ hostvars[ansible_host].environment }}/drive1", dest: /mnt/drive1 }
          - { src: "/mnt/nas/{{ hostvars[ansible_host].environment }}/drive2", dest: /mnt/drive2 }

    - name: display mounts
      debug:
        var: nfs_mounts

    - name: display each mount
      debug:
        var: item
      with_items: "{{ nfs_mounts }}"

    - name: mount
      mount:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
      with_items: "{{ nfs_mounts }}"

补充优化

可以简化变量引用逻辑,直接使用当前主机上下文的environment变量(无需通过hostvars索引):

- name: Define NFS mounts for current host
  set_fact:
    nfs_mounts:
      - { src: "/mnt/nas/{{ environment }}/drive1", dest: /mnt/drive1 }
      - { src: "/mnt/nas/{{ environment }}/drive2", dest: /mnt/drive2 }

修改后,循环任务就能正确获取已渲染的挂载配置,顺利执行挂载操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:15:25