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

如何在Ansible中为FortiGate按客户分组地址对象?

解决Fortinet Ansible模块中客户地址组的成员匹配问题

现有变量

customers:
  - name: CompanyX
    destination_addresses:
      - 192.168.0.0/24
      - 192.168.1.0/24

  - name: CompanyY
    destination_addresses:
      - 192.168.2.0/24
      - 192.168.3.0/24

已完成的地址对象创建任务

已成功为每个destination_addresses中的地址创建独立的地址对象,对应的Ansible任务如下:

- name: add address object for destination networks
  fortinet.fortios.fortios_firewall_address:
    state: present
    firewall_address:
      name: "{{ item.0.name }}-{{ item.1 }}"
      subnet: "{{ item.1 }}"
  loop: "{{ customers | subelements('destination_addresses') }}"

该任务生成的地址对象包括:

  • CompanyX-192.168.0.0/24
  • CompanyX-192.168.1.0/24
  • CompanyY-192.168.2.0/24
  • CompanyY-192.168.3.0/24

地址组创建的问题

当前创建地址组的任务会导致每个客户的地址组包含所有地址对象,而非仅对应客户的地址:

- set_fact:
    grp_members: "{{ grp_members | default([]) + [{ 'name': item.0.name ~ '-' ~ item.1 }] }}"
  loop: "{{ customers | subelements('destination_addresses') }}"
  loop_control:
    extended: yes

- name: create address group
  fortinet.fortios.fortios_firewall_addrgrp:
    state: present
    firewall_addrgrp:
      name: "{{ item.name }}"
      member: "{{ grp_members }}"
  loop: "{{ customers }}"

当前输出

grp_members变量会存储所有地址对象:

"grp_members": [
    {
        "name": "CompanyX-192.168.0.0/24"
    },
    {
        "name": "CompanyX-192.168.1.0/24"
    },
    {
        "name": "CompanyY-192.168.2.0/24"
    },
    {
        "name": "CompanyY-192.168.3.0/24"
    }
]

期望输出

每个客户的地址组仅包含自身对应的地址对象:
CompanyX对应的成员:

"grp_members": [
    {
        "name": "CompanyX-192.168.0.0/24"
    },
    {
        "name": "CompanyX-192.168.1.0/24"
    }
]

CompanyY对应的成员:

"grp_members": [
    {
        "name": "CompanyY-192.168.2.0/24"
    },
    {
        "name": "CompanyY-192.168.3.0/24"
    }
]

注:fortinet.fortios.fortios_firewall_addrgrp模块要求成员采用上述字典格式

解决方案

不需要提前合并所有成员到一个变量,而是在循环每个客户时,动态生成该客户对应的成员列表。以下是两种可行的实现方式:

方式一:直接在任务中生成成员列表

- name: create address group for each customer
  fortinet.fortios.fortios_firewall_addrgrp:
    state: present
    firewall_addrgrp:
      name: "{{ item.name }}"
      member: "{{ item.destination_addresses | map('regex_replace', '^(.*)$', '{\"name\": \"' ~ item.name ~ '-\\1\"}') | map('from_json') | list }}"
  loop: "{{ customers }}"

方式二:先预先生成每个客户的成员分组

- name: prepare address group members per customer
  set_fact:
    customer_groups: "{{ customer_groups | default([]) + [
      {
        'name': item.name,
        'members': item.destination_addresses | map('regex_replace', '^(.*)$', '{\"name\": \"' ~ item.name ~ '-\\1\"}') | map('from_json') | list
      }
    ] }}"
  loop: "{{ customers }}"

- name: create address group using prepared members
  fortinet.fortios.fortios_firewall_addrgrp:
    state: present
    firewall_addrgrp:
      name: "{{ item.name }}"
      member: "{{ item.members }}"
  loop: "{{ customer_groups }}"

两种方式的核心逻辑都是为每个客户单独处理其destination_addresses,生成仅属于该客户的成员字典列表,避免将所有成员合并到同一个变量中。

内容的提问来源于stack exchange,提问作者Greg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:40:28