如何在Ansible模块函数中嵌套循环实现Eth-Channel配置?
解决Ansible配置Cisco Eth-Channel的嵌套循环问题
问题场景
在group_vars中定义了如下Eth-Channel配置:
etherchannels: access2: - channelnumber: 1 interfaces: - FastEthernet 1/14 - FastEthernet 1/15 access1: - channelnumber: 1 interfaces: - FastEthernet 1/14 - FastEthernet 1/15
现有Playbook尝试配置这些Eth-Channel,但无法正确为每个通道添加所有成员接口:
- name: LAN Switches hosts: access tasks: - name: config unused access ports cisco.ios.ios_lag_interfaces: config: - name: "{{ item.channelnumber }}" members: - member: "{{ item.interface }}" mode: on loop: "{{ etherchannels[inventory_hostname] }}"
预期效果:
- 针对
etherchannels下的每个主机(access1、access2)执行配置 - 为每个主机定义对应的Eth-Channel(
name字段) - 为每个Eth-Channel添加所有列出的成员接口
问题分析
现有Playbook的核心错误:
- 循环项
item是包含channelnumber和interfaces列表的字典,但代码错误引用了不存在的item.interface字段 - 未对
interfaces列表进行遍历,无法生成多个成员配置项
解决方案
通过Ansible过滤器或Jinja2循环,将每个通道的interfaces列表转换为模块所需的members格式:
方法1:使用Ansible过滤器(推荐)
利用map和combine过滤器快速生成成员列表,需确保已安装community.general集合:
- name: LAN Switches hosts: access tasks: - name: Configure Eth-Channels cisco.ios.ios_lag_interfaces: config: - name: "{{ item.channelnumber }}" members: "{{ item.interfaces | map('community.general.dict_kv', 'member') | map('combine', {'mode': 'on'}) | list }}" loop: "{{ etherchannels[inventory_hostname] }}"
过滤器逻辑:
map('community.general.dict_kv', 'member'):将每个接口字符串转换为{'member': '接口名'}的字典map('combine', {'mode': 'on'}):为每个字典添加mode: on字段| list:将处理后的结果转换为列表,匹配members参数格式
方法2:使用Jinja2循环
若无法安装community.general集合,可直接用Jinja2模板循环生成成员项:
- name: LAN Switches hosts: access tasks: - name: Configure Eth-Channels cisco.ios.ios_lag_interfaces: config: - name: "{{ item.channelnumber }}" members: {% for intf in item.interfaces %} - member: "{{ intf }}" mode: on {% endfor %} loop: "{{ etherchannels[inventory_hostname] }}"
验证效果
执行Playbook后,针对access1的Eth-Channel 1会生成如下配置结构:
name: 1 members: - member: FastEthernet 1/14 mode: on - member: FastEthernet 1/15 mode: on
若扩展etherchannels配置添加更多通道(如channelnumber:2),模块会自动生成对应的多成员配置,完全符合预期需求。
内容的提问来源于stack exchange,提问作者Zach
相关产品推荐
相关产品推荐

