Automating Provisioning Template Migrations – FortiManager
- FA
- Feb 18, 2026
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:
- Go to Device Manager → Provisioning Templates in the ADOM.
- Use Export Templates to download an unencrypted JSON file.
- 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_proxypaths - 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:
- Login/SwitchADOM/Logout
This contains requests how to login(logout) to FortiManager using CSRF token method. - Export Templates
Initialize the Export process and then using GET request get the templates data in JSON format, which can be saved offline. - 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 templatesfmg_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:
- Login using GUI auth and capture the CSRF token from cookies.
- Prompt for ADOM (default root) and optionally switch to another ADOM via
/gui/session/adom. - Call
/deployment/export/templatewith:- 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
- Poll the created task via
/task/task/<id>until completion. - When done, call
/flatui/api/gui/deploy/exportto 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_exportsand 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:
Upload file
- POST to
/flatui/api/gui/deploy/import(multipart/form‑data) - Include CSRF token fields plus a
filepathfile part
- POST to
Trigger import task
- POST to
/cgi-bin/module/flatui/jsonwith a JSON payload for/deployment/import/template - Set
adomto the selected ADOM OID andfileto/var/tmp/deploy_import - Request runs as an asynchronous task (
create_task: "true")
- POST to
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 == 4usually means successstate == 5means “finished with errors” (for example, ADOM version mismatch)
In addition, it walks through line[] and history[] entries inside the task:
- Any entry with
err != 0is considered an error - Any entry whose
detail/msgcontainserror,mismatch, orinvalidis 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.