Ansible遍历spine_list时属性被覆盖问题求助
问题解决:避免Ansible循环中变量被覆盖
问题根源
你遇到的核心问题是:第一个set_fact任务循环时,每次迭代都会直接覆盖spine_int_B0和spine_int_B1这两个全局变量,循环结束后它们只会保留最后一个spine节点(1102)的接口拆分结果。后续的端口选择器策略任务循环时,所有节点都会复用这组值,导致前面的端口块被覆盖。
解决方案
方案1:直接在任务内处理接口拆分,取消单独的set_fact任务
不需要提前用set_fact存储变量,直接在uri任务的请求体里基于当前循环的spine_item计算接口拆分值,每个迭代都会独立计算,不会互相干扰:
- name: Spine Fabric Port Selector Policy uri: url: "https://{{ apic }}/api/mo/uni.json" method: POST body_format: json validate_certs: no headers: Cookie: "{{ apic_cookie }}" Accept: 'application/json' body: fabricSpPortP: attributes: dn: "uni/fabric/spportp-test" name: "{{ macsec_policy_names[6].macsec_spine_fabric_ip_policyname }}" children: - fabricSFPortS: attributes: annotation: '' name: "test2" type: "range" children: - fabricRsSpPortPGrp: attributes: annotation: '' tDn: "uni/fabric/funcprof/spportgrp-test3" - fabricPortBlk: attributes: annotation: '' fromCard: "{{ spine_item.int_A.split('/')[0] | regex_replace('(?i)^eth', '') }}" fromPort: "{{ spine_item.int_A.split('/')[1] | regex_replace('(?i)^eth', '') }}" name: "Block" # 直接在当前循环内计算int_B的拆分值 toCard: "{{ spine_item.int_B.split('/')[0] | regex_replace('(?i)^eth', '') }}" toPort: "{{ spine_item.int_B.split('/')[1] | regex_replace('(?i)^eth', '') }}" return_content: yes status_code: [200] register: spine_fabric_ps_result loop: "{{ spine_list }}" loop_control: loop_var: spine_item
方案2:预处理spine_list,添加拆分后的接口字段
如果需要多次复用拆分后的接口值,可以先通过set_fact生成一个包含拆分后字段的新列表,后续任务直接引用该列表的字段:
- name: 预处理spine_list,添加拆分后的接口字段 set_fact: processed_spine_list: "{{ processed_spine_list | default([]) + [ spine_item | combine({ 'int_A_card': spine_item.int_A.split('/')[0] | regex_replace('(?i)^eth', ''), 'int_A_port': spine_item.int_A.split('/')[1] | regex_replace('(?i)^eth', ''), 'int_B_card': spine_item.int_B.split('/')[0] | regex_replace('(?i)^eth', ''), 'int_B_port': spine_item.int_B.split('/')[1] | regex_replace('(?i)^eth', '') }) ] }}" loop: "{{ spine_list }}" loop_control: loop_var: spine_item - name: Spine Fabric Port Selector Policy uri: url: "https://{{ apic }}/api/mo/uni.json" method: POST body_format: json validate_certs: no headers: Cookie: "{{ apic_cookie }}" Accept: 'application/json' body: fabricSpPortP: attributes: dn: "uni/fabric/spportp-test" name: "{{ macsec_policy_names[6].macsec_spine_fabric_ip_policyname }}" children: - fabricSFPortS: attributes: annotation: '' name: "test2" type: "range" children: - fabricRsSpPortPGrp: attributes: annotation: '' tDn: "uni/fabric/funcprof/spportgrp-test3" - fabricPortBlk: attributes: annotation: '' fromCard: "{{ spine_item.int_A_card }}" fromPort: "{{ spine_item.int_A_port }}" name: "Block" toCard: "{{ spine_item.int_B_card }}" toPort: "{{ spine_item.int_B_port }}" return_content: yes status_code: [200] register: spine_fabric_ps_result loop: "{{ processed_spine_list }}" loop_control: loop_var: spine_item
额外注意
检查第一个set_fact任务的循环列表是macsec_spine_list,但第二个任务用的是spine_list,如果这两个列表不是同一个,会导致数据不匹配,建议统一列表名称。
内容的提问来源于stack exchange,提问作者pawan u
相关产品推荐
相关产品推荐

