Ansible跨目录调用角色时,如何加载环境专属group_vars变量?
文件夹结构
ansible ├── deployment │ └── group_vars | └── dev | └── main.yml | └── all.yml | └── roles | └── role1 | └── tasks | └── task1.yml | └── deploy.yml ├── environment │ └── group_vars | └── roles | └── role2 | └── tasks | └── task2.yml | └── site.yml ├── infra | └── group_vars | └── roles | └── site.yml
场景与当前配置
我需要运行environment目录下的task2.yml,该任务会调用deployment目录下role1中的task1.yml。已在ansible.cfg中添加配置:
roles_path = /home/ansible/deployment/roles
同时在task2.yml中添加了以下代码:
- name: 引入通用变量 ansible.builtin.include_vars: file: "{{ item }}" with_fileglob: - "/home/ansible/deployment/group_vars/all.yml" # 包含通用变量 - name: 部署应用 include_role: name: role1
当前配置可正常运行,但当需要使用/deployment/group_vars/<env>/main.yml中的环境相关变量时,出现如下错误:
"The task includes an option with an undefined variable. The error was: 'some_var' is undefined.
运行playbook的命令:
ansible-playbook site.yml -i dev_hosts -u user --ask-pass -K --vault-id @prompt --tags "role1"
提问:是否可以加载/deployment/group_vars/<env>/main.yml,从而正确解析ansible/deployment/group_vars/dev中的变量?
当然可以加载环境相关的group_vars文件,以下是几种可靠的实现方式:
方法1:动态匹配环境变量文件
利用命令传入的环境参数,动态加载对应环境的变量文件。修改task2.yml中的变量引入部分:
- name: 引入通用变量 ansible.builtin.include_vars: file: "/home/ansible/deployment/group_vars/all.yml" - name: 引入环境专属变量 ansible.builtin.include_vars: file: "/home/ansible/deployment/group_vars/{{ env }}/main.yml"
运行命令时通过-e参数传入环境值:
ansible-playbook site.yml -i dev_hosts -u user --ask-pass -K --vault-id @prompt --tags "role1" -e "env=dev"
如果你的inventory文件(dev_hosts)中已经给主机定义了env变量,也可以直接用{{ env }}而不需要手动传参。
方法2:设置额外的group_vars路径
在ansible.cfg中添加deployment目录下的group_vars到变量搜索路径:
[defaults] roles_path = /home/ansible/deployment/roles group_vars_path = /home/ansible/deployment/group_vars:/home/ansible/environment/group_vars
这样Ansible会自动从指定路径加载对应主机组的变量文件,无需手动用include_vars引入。注意要确保inventory中的主机组名称和deployment/group_vars下的环境目录名一致(比如dev组对应dev目录)。
方法3:引入deployment的playbook
如果deployment/deploy.yml本身已经处理了变量加载逻辑,可以在environment/site.yml中直接引入该playbook:
- import_playbook: ../deployment/deploy.yml
这样会继承deploy.yml中的变量加载规则,无需在task2.yml中重复处理。
内容的提问来源于stack exchange,提问作者chastain

