如何在Nornir中使用Ansible风格动态清单及现有host_vars配置
你对原生nornir.plugins.inventory.ansible.AnsibleInventory的限制判断是正确的,该插件默认仅支持读取单个清单文件,无法直接适配多host_vars文件的加载场景。以下是两种适配你工作流的解决方案:
解决方案
方案1:自定义Nornir动态Inventory插件(最适配你的工作流)
你可以直接基于现有Ansible动态inventory脚本改造为Nornir的自定义Inventory插件,无需改动现有host_vars多文件结构,完全匹配你"先生成host_vars下的yaml、运行时直接调用"的需求:
- 编写自定义inventory逻辑,示例代码如下:
from nornir.core.inventory import Inventory, Host, Groups, ParentGroups import yaml from pathlib import Path def custom_ansible_dynamic_inventory(host_vars_dir: str = "./host_vars/") -> Inventory: hosts = {} groups = {} # 遍历所有host_vars文件加载主机信息 for host_file in Path(host_vars_dir).glob("*.yml"): with open(host_file, "r", encoding="utf-8") as f: host_data = yaml.load(f, Loader=yaml.FullLoader) hostname = host_data.pop("hostname") host_groups = host_data.pop("host_groups", []) # 初始化主机对象,host_vars里的所有字段直接作为主机数据 hosts[hostname] = Host( name=hostname, groups=ParentGroups([g for g in host_groups]), data=host_data ) # 同步更新组信息 for group in host_groups: if group not in groups: groups[group] = Groups(name=group) return Inventory(hosts=hosts, groups=groups) # 初始化Nornir时直接调用自定义inventory from nornir import InitNornir nr = InitNornir( inventory={ "plugin": custom_ansible_dynamic_inventory, "options": { "host_vars_dir": "./host_vars/" } } )
- 优势:无需额外生成中间清单文件,直接复用现有host_vars目录结构,动态加载逻辑完全可控。
方案2:预合并host_vars为单文件适配原生AnsibleInventory插件
如果你不想自定义插件,可以在每次运行Nornir前,先运行你现有的动态inventory脚本生成符合AnsibleInventory要求的单文件清单:
- 改造现有脚本,除了输出组信息外,同时把所有host_vars的内容合并到单文件的hosts字段下
- 生成的单文件清单格式参考:
all: children: group1: hosts: host1: # 这里放host1对应的所有host_vars字段 host2: {} group2: hosts: host2: {}
- 初始化Nornir时直接调用原生插件:
from nornir import InitNornir from nornir.plugins.inventory.ansible import AnsibleInventory nr = InitNornir( inventory={ "plugin": AnsibleInventory, "options": { "hostsfile": "./生成的合并后清单文件.yaml" } } )
- 优势:复用现有脚本的逻辑,改动量小。
内容的提问来源于stack exchange,提问作者Shepardos
相关产品推荐
相关产品推荐

