You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible实现双层嵌套循环的方法求助

Ansible实现双层嵌套循环的方法求助

看起来你已经搞定了第一层遍历vlans字典的操作,但卡在了嵌套遍历mode这一步对吧?我来帮你捋清楚怎么实现这个需求——毕竟你的变量结构里,每个VLAN的mode又是一个存着端口模式和端口列表的字典,确实需要多做一步处理。

首先先明确你的变量结构:vlans是一个顶层字典,每个键(比如Servers、Clients)对应的值里,mode又是一个子字典——键是端口模式(tagged/untagged),值是逗号分隔的端口字符串。要实现每个端口单独执行配置任务,我们得先把这些嵌套的结构拆成扁平的、每个条目对应一个端口配置的列表。

解决方案:先预处理变量,再循环执行任务

我推荐用set_fact先把变量转换成适合循环的结构,把每个端口的VLAN ID、端口号、端口模式一一对应起来:

- name: 预处理VLAN变量,生成单端口配置列表
  set_fact:
    vlan_port_list: |
      {% set result = [] %}
      {% for vlan_name, vlan_data in vlans.items() %}
        {% # 跳过没有mode配置的VLAN,比如Printers %}
        {% if vlan_data.mode is defined %}
          {% # 遍历每个端口模式(tagged/untagged) %}
          {% for mode, ports_str in vlan_data.mode.items() %}
            {% # 把逗号分隔的端口字符串拆成单个端口 %}
            {% for port in ports_str.split(',') %}
              {% set _ = result.append({
                'vlan_id': vlan_data.vlan_id,
                'port_id': port.strip(), # 去掉端口号前后可能的空格
                'port_mode': mode
              }) %}
            {% endfor %}
          {% endfor %}
        {% endif %}
      {% endfor %}
      {{ result }}

有了这个预处理后的vlan_port_list,接下来的配置任务就简单了,直接循环这个列表就行:

- name: 配置VLAN端口成员
  arubaoss_vlan:
    command: config_vlan_port
    config: "create"
    vlan_id: "{{ item.vlan_id }}"
    port_id: "{{ item.port_id }}"
    port_mode: "{{ item.port_mode | regex_replace('^tagged$', 'POM_TAGGED_STATIC') | regex_replace('^untagged$', 'POM_UNTAGGED') | regex_replace('^forbid$', 'POM_FORBIDDEN') }}"
    api_version: "{{ ansible_api_version }}"
    use_ssl: "{{ ansible_use_ssl }}"
    port: "{{ ansible_port }}"
    host: "{{ ansible_host }}"
    username: "{{ ansible_user }}"
    password: "{{ ansible_password }}"
  loop: "{{ vlan_port_list }}"
  tags:
    - vlans
    - vlans_mode

验证预处理结果

你可以加个debug任务来确认预处理后的列表是否符合预期:

- name: 调试预处理后的VLAN端口配置
  debug:
    msg: "VLAN {{ item.vlan_id }} - 端口{{ item.port_id }} - 模式{{ item.port_mode }}"
  loop: "{{ vlan_port_list }}"
  tags:
    - debug

这个debug任务会输出类似这样的内容,每个端口都是单独的条目,完全符合我们的需求:

ok: [sw39stack01.group.corp] => (item={'vlan_id': 10, 'port_id': '1/1', 'port_mode': 'tagged'}) => {
    "msg": "VLAN 10 - 端口1/1 - 模式tagged"
}
ok: [sw39stack01.group.corp] => (item={'vlan_id': 10, 'port_id': '1/2', 'port_mode': 'tagged'}) => {
    "msg": "VLAN 10 - 端口1/2 - 模式tagged"
}
ok: [sw39stack01.group.corp] => (item={'vlan_id': 10, 'port_id': '1/3', 'port_mode': 'untagged'}) => {
    "msg": "VLAN 10 - 端口1/3 - 模式untagged"
}
...

为什么不用with_subelements?

你之前试过的with_subelements其实也能用,但需要先把mode字典转换成列表结构(比如把{'tagged': '1/1,1/2'}变成[{'mode': 'tagged', 'ports': '1/1,1/2'}]),但这样还是绕不开拆分端口字符串的步骤,反而不如直接用set_fact预处理来得直观。

这个方法应该能完美解决你的嵌套循环需求,你可以试试这个方案~

备注:内容来源于stack exchange,提问作者Isopote42

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 16:24:50