如何在Ansible Playbook中展开VLAN范围列表为完整数字列表?
问题:在Ansible中展开VLAN范围列表
我有一个格式为 allowed_vlans: "1,20-22,37,39-40,600,1011-1013,1025" 的VLAN列表,需要将其转换为展开后的完整数字列表:allowed_vlans_range: "1, 20, 21, 22, 37, 39, 40, 600, 1011, 1012, 1013, 1025"
限制条件
- 仅允许使用单个Playbook文件
- 不能使用外部Jinja2模板(可嵌入Playbook内)
- 禁止使用外部Python插件
已完成的前置步骤
1. 获取端口通道允许VLAN列表
已通过以下任务获取每个端口通道的允许VLAN配置:
tasks: - name: 获取端口通道接口信息 cisco.nxos.nxos_facts: gather_subset: interfaces gather_network_resources: interfaces register: pc_info - name: 获取端口通道接口允许的VLAN列表 vars: port_channels_list: "{{ pc_info.ansible_facts.ansible_network_resources.interfaces | map(attribute='name') | flatten | to_json | from_json | regex_findall('port-channel[0-9]+') }}" cisco.nxos.nxos_command: commands: - show run interface {{ item }} | grep "allowed vlan" loop: "{{ port_channels_list }}" register: pc_allowed_vlans
2. 提取范围格式的VLAN项
已从结果中提取出类似20-22、39-40的范围项:
- name: 解析允许的VLAN vars: allowed_vlans: "{{ item.stdout | regex_findall('[0-9]+(?:-[0-9]+)?') }}" allowed_vlans_ranges: "{{ allowed_vlans | regex_findall('[0-9]+-[0-9]+') }}" debug: msg: "{{ allowed_vlans_ranges }}" loop: "{{ pc_allowed_vlans.results }}" register: allowed_vlans_range
解决方案:嵌入Jinja2逻辑实现范围展开
可以在Playbook中直接嵌入Jinja2逻辑,逐个处理每个VLAN项(单个数字或范围),最终生成展开后的完整列表。以下是完整任务实现:
- name: 展开VLAN范围并生成完整列表 vars: # 提取纯VLAN字符串(去掉命令输出前缀)并分割为单个项 vlan_items: "{{ item.stdout | regex_replace('.*allowed vlan ', '') | split(',') }}" # Jinja2逻辑:展开所有VLAN项 expand_vlan_logic: | {% set expanded_list = [] %} {% for vlan in vlan_items %} {% if '-' in vlan %} {% set start = vlan.split('-')[0] | int %} {% set end = vlan.split('-')[1] | int %} {% for num in range(start, end + 1) %} {% do expanded_list.append(num | string) %} {% endfor %} {% else %} {% do expanded_list.append(vlan) %} {% endif %} {% endfor %} {{ expanded_list | join(', ') }} debug: msg: "端口通道 {{ item.item }} 展开后的VLAN列表: {{ expand_vlan_logic }}" loop: "{{ pc_allowed_vlans.results }}" register: expanded_vlans
逻辑说明
- 提取并分割VLAN项:用
regex_replace移除命令输出中的allowed vlan前缀,再用split(',')将字符串拆分为独立的VLAN项列表 - 展开范围项:
- 遍历每个VLAN项,若包含
-则分割为起始和结束数字,通过range生成中间所有数字 - 单个VLAN数字直接加入结果列表
- 遍历每个VLAN项,若包含
- 拼接结果:用
join(', ')将展开后的数字列表转换为带空格分隔的字符串
如果需要将结果存储为变量供后续任务使用,可将debug模块替换为set_fact,或者直接引用expanded_vlans.results中的对应字段。
内容的提问来源于stack exchange,提问作者Karl
相关产品推荐
相关产品推荐

