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

Ansible变量访问失败:报错'dict object' has no attribute 'globalname'

Ansible加载目录变量报错:'dict object' has no attribute 'globalname'

问题场景

执行的Ansible剧本:

---
- hosts: localhost
  gather_facts: no
  vars:
    var_folder_path: /home/play
  tasks:
    - name: Include all yaml files in directories
      include_vars:
        dir: "{{ var_folder_path }}/vars"
        extensions:
          - 'yaml'

    - name: "Print Variable Name"
      shell: echo "{{ item }}"
      loop:
        - "{{ global.globalname.property.Name }}"
        - "{{ S3.secret }}"

/home/play/vars下的变量文件:

example_1.yaml

global:
  globalname:
    property:
      cipher: DEFAULT
      client:
        type: dynamic
      Name: test-run

example_2.yaml

gcp:
  keyname: sample-run
S3:
  secret: run
Resources: false
celery:
  resources:
    limits:
      cpu: 5

执行报错:

fatal: [localhost]: FAILED! => {"msg": "'dict object' has no attribute 'globalname'"}

问题原因

使用include_vars的dir参数加载目录下的变量文件时,默认行为是将每个文件的内容封装到一个以文件名(不含扩展名)命名的字典变量中,而非直接将文件内的顶级键导入当前play的命名空间。

具体来说:

  • example_1.yaml的内容会被存入example_1变量,结构为example_1: {global: {...}}
  • example_2.yaml的内容会被存入example_2变量,结构为example_2: {gcp: {...}, S3: {...}}

直接访问global.globalname会报错,因为当前命名空间中不存在顶级的global变量,你误把封装后的字典结构当成了直接导入的顶级键。

解决方案

有两种方式可以解决这个问题:

方案1:修改变量访问路径,适配默认封装规则

通过文件名对应的变量来访问内部的键:

- name: "Print Variable Name"
  shell: echo "{{ item }}"
  loop:
    - "{{ example_1.global.globalname.property.Name }}"
    - "{{ example_2.S3.secret }}"

方案2:启用flat: yes参数,直接合并所有顶级键到命名空间

在include_vars任务中添加flat: yes参数,Ansible会跳过按文件名封装的步骤,直接将所有变量文件中的顶级键合并到当前play的命名空间,你就可以按原方式访问变量:

- name: Include all yaml files in directories
  include_vars:
    dir: "{{ var_folder_path }}/vars"
    extensions:
      - 'yaml'
    flat: yes

注意:如果多个变量文件中有同名的顶级键,后面加载的文件会覆盖前面的定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:15:06