Automating Provisioning Template Migrations – FortiManager

If you work with FortiManager regularly, you probably rely on provisioning templates to standardize configuration across large numbers of FortiGate devices. FortiManager’s GUI already lets you export and import these templates between ADOMs or even between different FortiManagers. But if you’re doing this often—or as part of a migration—it’s very handy to automate the process.

In this article I’ll show a complete, working approach to:

  • Export provisioning templates from a chosen ADOM using Python
  • Download the same JSON file that the GUI would generate
  • Import that file into another ADOM

All of this is done through the internal GUI (flatui) APIs (instead of JSON-RPC).

You can use either the Python scripts or the Postman collection:

- GitHub: [FMG_Python – Export_Import_Provisioning_Templates]  
- Postman: [FortiManager Export/Import Provisioning Templates]

FortiManager officially supports exporting and importing provisioning templates through the GUI. The workflow is:

  1. Go to Device Manager → Provisioning Templates in the ADOM.
  2. Use Export Templates to download an unencrypted JSON file.
  3. On the target ADOM/FortiManager, drag‑and‑drop that JSON into Import.

That’s perfectly fine for one‑off migrations. Where it becomes painful is when you need to: Repeat the operation across multiple ADOMs or FortiManagers.

How the Approach Works

Instead of using the public JSON‑RPC API, these scripts call the same flatui endpoints FortiManager’s GUI uses (tested with v7.4 and 7.6 – this might change in future):

  • Login: /cgi-bin/module/flatui_auth
  • ADOM listing & switching: /cgi-bin/module/flatui_proxy paths
  • Export execution: /cgi-bin/module/flatui/forward -> /deployment/export/template
  • Export download: /flatui/api/gui/deploy/export
  • Import upload: /flatui/api/gui/deploy/import
  • Import execution: /cgi-bin/module/flatui/json -> /deployment/import/template

That means the JSON export file you download is identical to what you’d get via the GUI. You can even edit it offline and then import it again.

ADOM Handling
  • Log in and default to root ADOM (OID 3).
  • List ADOMs with name, OID, version, and type.
  • Using the Switch ADOM request can change the ADOM (in case of Python script it will prompt if you want to change ADOM

The Postman collection consists of three folders:

  1. Login/SwitchADOM/Logout
    This contains requests how to login(logout) to FortiManager using CSRF token method.
  2. Export Templates
    Initialize the Export process and then using GET request get the templates data in JSON format, which can be saved offline.
  3. Import Templates
    Initialize  the import process by uploading (selecting path) of the JSON file (exported templates) then import the templates. Using the switch ADOM requests from #1, templates can be imported to different ADOM (but ADOM version should match).

Using Python Automation:

The Python scripts below wrap this process (including switching ADOM – if required) into two repeatable steps:

  • fmg_export_templates.py – export and download templates
  • fmg_import_templates.py – upload and import templates into another ADOM

Script 1 – Exporting Provisioning Templates

At a high level, the export script does the following:

  1. Login using GUI auth and capture the CSRF token from cookies.
  2. Prompt for ADOM (default root) and optionally switch to another ADOM via /gui/session/adom.
  3. Call /deployment/export/template with:
    • Target ADOM OID
    • A list of template categories (system templates, CLI templates, QoS profiles, SD‑WAN, etc.)
    • create_task: "true" to run as an asynchronous task
  4. Poll the created task via /task/task/<id> until completion.
  5. When done, call /flatui/api/gui/deploy/export to download the export file.

The file is saved under a local directory such as ./fmg_exports with a name like:

2050_export_template_-FMG-VMTMXXXXXXX-XXXX.json

 

Export script console output

When you run the export script, you’ll see a full console report showing login status, ADOM selection, task creation, task polling, and the final saved export file path.

[2026-02-18T17:41:48Z] Logging in to FortiManager at 10.128.210.118...
[2026-02-18T17:41:49Z] Login successful. CSRF token acquired.

Default ADOM is Root (OID=3). Do you want to change ADOM? [y/N]: n
[2026-02-18T17:42:01Z] Proceeding with Root ADOM (OID=3).

[2026-02-18T17:42:01Z] Initiating template export for ADOM OID 3...
[2026-02-18T17:42:01Z] Export task created. Task ID: 2050, File: export_template_-FMG-VMTMXXXXXXXX-uwjS3F.json
[2026-02-18T17:42:01Z] Polling task 2050... 0% 10% 25% 60% 90% 100%
[2026-02-18T17:42:16Z] Task 2050 completed successfully.
[2026-02-18T17:42:16Z] Downloading export file...
[2026-02-18T17:42:17Z] Export file saved to: ./fmg_exports/2050_export_template_-FMG-VMTMXXXXXXX-uwjS3F.json

=================================================================
       FORTIMANAGER TEMPLATE EXPORT REPORT
=================================================================
  Timestamp   : 2026-02-18T17:42:17Z
  FMG Host    : 10.128.210.118
  ADOM        : root (OID: 3)
  Task ID     : 2050
  Export File : export_template_-FMG-VMTMXXXXXXXX-uwjS3F.json
  Saved To    : ./fmg_exports/2050_export_template_-FMG-VMTMXXXXXXXX-uwjS3F.json
  Duration    : 29.3s
-----------------------------------------------------------------
  Categories Exported (16):
    ✔  bonjour-prof
    ✔  cli-prof
    ✔  cert-prof
    ✔  dev-blueprint
    ✔  fext-prof
    ✔  switch-prof
    ✔  ips-prof
    ✔  ipsec-prof
    ✔  cst-prof
    ✔  qos-prof
    ✔  sdwan-overlay-prof
    ✔  sdwan-prof
    ✔  route-prof
    ✔  sys-prof
    ✔  tmplgrp-prof
    ✔  cr-prof
=================================================================
[2026-02-18T17:42:17Z] Logging out...
[2026-02-18T17:42:17Z] Logged out.

Script 2 – Importing Provisioning Templates

The import script is essentially the reverse pipeline.

  • Similar to the export part, after logging in script prompts to either keep the default root ADOM to select any other ADOM.
  • Then the script lists all files under ./fmg_exports and asks you to type the file name:
Available files in ./fmg_exports:
  - 2050_export_template_-FMG-VMTMXXXXXXX-uwjS3F.json

Enter export file name (as listed above):

It then constructs the full path and uses that for upload. Import consists of two steps:

    1. Upload file

      • POST to /flatui/api/gui/deploy/import (multipart/form‑data)
      • Include CSRF token fields plus a filepath file part

       

    2. Trigger import task

      • POST to /cgi-bin/module/flatui/json with a JSON payload for /deployment/import/template
      • Set adom to the selected ADOM OID and file to /var/tmp/deploy_import
      • Request runs as an asynchronous task (create_task: "true")

Polling and Error Detection

 

The script polls /task/task/<id> until FortiManager marks the task finished (state 4 or 5, percent 100, or all lines processed). It then inspects the task details:

  • state == 4 usually means success
  • state == 5 means “finished with errors” (for example, ADOM version mismatch)

In addition, it walks through line[] and history[] entries inside the task:

  • Any entry with err != 0 is considered an error
  • Any entry whose detail/msg contains error, mismatch, or invalid is also flagged

This is important because FortiManager can show “Task finished with errors” even while overall progress is 100%. Without inspecting those lines, simple scripts will wrongly report “success”.

The script prints a detailed console report:

=================================================================
       FORTIMANAGER TEMPLATE IMPORT REPORT
=================================================================
  Timestamp   : 2026-02-18T18:15:59Z
  FMG Host    : 10.128.210.118
  ADOM        : Test (OID: 750)
  Task ID     : 2054
  Source File : ./fmg_exports\2050_export_template_-FMG-VMTMXXXXXXXX-uwjS3F.json
  Duration    : 30.9s
-----------------------------------------------------------------
  Overall Task State : 4
  Progress           : 100%

=================================================================

When to Use This Approach

This automation is a good fit when:

  • You are migrating provisioning templates between lab and production FortiManagers.
  • You want a repeatable way to sync templates between ADOMs.
  • You need logs and visibility beyond what a single manual GUI import gives you.
  • You are building internal tools for NetOps/SecOps engineers who prefer a CLI workflow.

If you only need to move a handful of templates once, the GUI export/import functions are still perfectly fine.

Scroll to Top