如何在拥有独立group_vars的多环境中运行Ansible Playbook?
嘿,我来帮你搞定这个问题!你现在遇到的核心痛点是:当你用ansible-playbook main.yml -i inventory/prod时,Ansible默认不会递归处理子目录里的Inventory配置和对应的group_vars——它只会扫描prod目录下的Inventory文件,所以虽然能识别到各个子环境的主机,但每个子目录里的group_vars/all.yml没被加载,导致Playbook跑不起来。而指定具体子目录(比如prod1)时,Ansible会把该目录当作独立的Inventory根目录,自动加载它下面的hosts.yml和group_vars,所以一切正常。
下面给你几个实用的解决方案,按上手难度和维护性排序:
方案1:用通配符一键加载所有子环境
这是最快捷的方式,直接在-i参数里用通配符匹配prod下的所有子目录:
ansible-playbook main.yml -i inventory/prod/prod*
这个命令会自动匹配prod1、prod2、prod3三个目录,每个目录的hosts.yml和对应的group_vars/all.yml都会被正确加载,完全满足你的需求,不用改任何文件。
方案2:给prod目录加个入口Inventory文件
如果你不想每次都敲通配符,可以在inventory/prod目录下创建一个hosts.yml(Ansible默认会优先找这个文件名),内容如下:
# inventory/prod/hosts.yml all: children: prod1: inventory: ./prod1 prod2: inventory: ./prod2 prod3: inventory: ./prod3
这样以后你只需要执行ansible-playbook main.yml -i inventory/prod,Ansible就会通过这个入口文件,自动加载所有子目录的Inventory和对应的变量。如果以后新增prod4,只需要在这个文件里加一行对应的配置就行。
方案3:调整目录结构(长期维护首选)
如果你的环境会持续扩展,建议按Ansible最佳实践调整目录结构,把group_vars集中到prod目录下,按环境分组管理:
- inventory - prod - hosts.yml # 在这里定义所有prod环境的主机分组 - group_vars - prod1.yml # 把原prod1/group_vars/all.yml的内容移到这里 - prod2.yml - prod3.yml - all.yml # 所有prod环境共享的通用变量 - nonprod ...
然后在hosts.yml里定义各个环境的主机:
# inventory/prod/hosts.yml all: children: prod1: hosts: server-prod1-01: ansible_host: 192.168.1.101 # 更多prod1主机... prod2: hosts: server-prod2-01: ansible_host: 192.168.1.102 # 更多prod2主机... prod3: hosts: server-prod3-01: ansible_host: 192.168.1.103 # 更多prod3主机...
这种结构更清晰,变量管理更集中,后续新增环境也更方便。
方案4:用find命令动态生成Inventory列表
如果你不想改任何文件或目录结构,可以用find命令动态找出所有子目录的hosts.yml,作为Inventory源:
ansible-playbook main.yml -i <(find inventory/prod -name "hosts.yml")
这个命令会自动收集prod下所有子目录的hosts.yml,并逐个加载对应的group_vars,效果和指定多个-i参数一样,但更简洁。
验证方法
不管用哪种方案,你都可以先执行下面的命令,确认所有主机和变量都被正确加载:
ansible-inventory -i inventory/prod --list
如果输出里能看到各个prod环境的主机,以及对应的变量,就说明配置没问题了,再运行Playbook就不会出错啦。
内容的提问来源于stack exchange,提问作者Aaron

