如何在Ansible中格式化CSV数据并通过循环配置设备接口?
实现方案:将CSV数据转换为host-接口列表结构
先明确预期的目标结构
我们需要把read_csv输出的行级字典列表,转换成如下格式,方便subelements遍历:
[ { "host": "switch1", "interfaces": [ {"interface": "Gi0/1", "ip": "192.168.1.1", "mask": "255.255.255.0"}, {"interface": "Gi0/2", "ip": "192.168.2.1", "mask": "255.255.255.0"} ] }, { "host": "switch2", "interfaces": [ {"interface": "Gi0/1", "ip": "10.0.0.1", "mask": "255.255.255.0"} ] } ]
方法1:用基础Ansible过滤器实现(无需额外依赖)
适合新手,不需要安装额外集合,逻辑直观:
假设你的CSV文件switch_interfaces.csv内容如下:
host,interface,ip,mask switch1,Gi0/1,192.168.1.1,255.255.255.0 switch1,Gi0/2,192.168.2.1,255.255.255.0 switch2,Gi0/1,10.0.0.1,255.255.255.0
对应的Playbook代码:
- name: 配置设备接口 hosts: localhost vars: csv_path: "./switch_interfaces.csv" tasks: - name: 读取CSV文件 read_csv: path: "{{ csv_path }}" register: raw_csv_data - name: 转换为host-接口列表结构 set_fact: device_interface_data: "{{ device_interface_data | default([]) + [{'host': host_name, 'interfaces': interface_list}] }}" loop: "{{ raw_csv_data.list | groupby('host') }}" loop_control: loop_var: host_group vars: host_name: "{{ host_group.0 }}" interface_list: "{{ host_group.1 }}" - name: 遍历设备+接口执行配置 debug: msg: "正在配置设备 {{ item.0.host }} 的接口 {{ item.1.interface }}:IP {{ item.1.ip }}/{{ item.1.mask }}" # 实际场景替换为你的API配置模块(比如ios_config、nxos_api等) loop: "{{ device_interface_data | subelements('interfaces') }}"
关键步骤解释:
groupby('host'):将原始CSV行数据按host字段分组,得到(主机名, 该主机所有接口行列表)的元组集合- 循环分组结果,用
set_fact逐个构建包含host和interfaces的字典,最终合并成目标列表 subelements('interfaces'):将每个设备的接口列表展开,实现"设备-接口"的双层循环
方法2:用链式过滤器简化代码(需community.general集合)
如果安装了community.general集合,可以用更简洁的过滤器链式调用:
- name: 转换为host-接口列表结构 set_fact: device_interface_data: > {{ raw_csv_data.list | groupby('host') | map('extract', 1) | map('community.general.dict_kv', 'interfaces') | zip(raw_csv_data.list | groupby('host') | map('extract', 0)) | map('combine') | list }}
逻辑说明:
map('extract', 1):取出分组后的接口行列表community.general.dict_kv:将列表包装为{interfaces: [...]]}的字典zip:将主机名列表和上述字典列表配对combine:将主机名字典({'host': 'xxx'})和接口列表字典合并成最终结构
注意事项
- 确保CSV中的
host字段值准确,同一设备的所有接口行必须使用相同的host值 - 如果CSV字段名不是
host,需要同步修改groupby的参数(比如groupby('device_name')) - 实际配置时,将
debug模块替换为对应厂商的API配置模块,比如cisco.ios.ios_interface或自定义API调用模块
内容的提问来源于stack exchange,提问作者dmgeurts
相关产品推荐
相关产品推荐

