Ansible嵌套循环字典变量问题:Cisco ACI桥域配置异常排查
解决Cisco ACI多主机批量创建桥域的问题
1. 字典自引用报错的解决
Ansible变量字典中,同一层级的key无法互相引用(变量解析时不会提前解析同字典内的其他key),直接在字典内用zone生成formatted_name会触发undefined错误。解决方式是把格式化名称的生成逻辑移到任务中,避免字典内自引用。
示例变量文件(vars/aci_bd_vars.yml)
# 只存储基础配置,不包含自引用的格式化名称 bridge_domains: bd_1: zone: "Zone_3CHR" vlan_id: 100 bd_2: zone: "Zone_3CHR" vlan_id: 200 bd_3: zone: "Zone_4CHR" vlan_id: 300
2. 修复仅bd_2创建成功的问题
之前的Inventory分组调整后仅bd_2成功,大概率是循环逻辑错误,没有实现每个主机遍历所有桥域的全量覆盖。以下是两种可靠的实现方式:
方式一:任务内直接拼接格式化名称
Playbook会在aci_hosts分组的每台主机上执行,任务内遍历所有桥域,直接在ACI模块参数中拼接生成formatted_name:
- name: 批量在ACI主机创建桥域 hosts: aci_hosts gather_facts: false vars_files: - vars/aci_bd_vars.yml - vars/aci_credentials.yml # 存储username、password等通用凭证 tasks: - name: 创建桥域 cisco.aci.aci_bd: host: "{{ inventory_hostname }}" username: "{{ aci_username }}" password: "{{ aci_password }}" validate_certs: false bd: "{{ item.value.zone }}_{{ item.key }}" # 动态拼接格式化名称 vlan: "{{ item.value.vlan_id }}" state: present loop: "{{ bridge_domains | dict2items }}"
方式二:提前用set_fact生成格式化桥域列表
如果需要更复杂的格式化规则,先通过set_fact整理好所有桥域的完整配置,再循环创建:
- name: 批量在ACI主机创建桥域 hosts: aci_hosts gather_facts: false vars_files: - vars/aci_bd_vars.yml - vars/aci_credentials.yml tasks: - name: 生成带格式化名称的桥域列表 set_fact: formatted_bd_list: "{{ formatted_bd_list | default([]) + [ {'bd_name': item.value.zone ~ '_' ~ item.key, 'vlan': item.value.vlan_id} ] }}" loop: "{{ bridge_domains | dict2items }}" - name: 创建所有桥域 cisco.aci.aci_bd: host: "{{ inventory_hostname }}" username: "{{ aci_username }}" password: "{{ aci_password }}" validate_certs: false bd: "{{ item.bd_name }}" vlan: "{{ item.vlan }}" state: present loop: "{{ formatted_bd_list }}"
关键注意事项
- 确保Inventory中
aci_hosts分组包含所有目标ACI设备 - 凭证变量(
aci_username、aci_password)建议存储在加密文件中(用ansible-vault加密) - 若需要按站点区分桥域配置,可在变量字典中添加站点维度,再通过
when条件或嵌套循环筛选
内容的提问来源于stack exchange,提问作者NotGene
相关产品推荐
相关产品推荐

