In a previous blog post, the ability to leverage CLI scripts with variables was explained. This served as an introduction to the feature but did not cover all of the capabilities. For example, in the previous blog, the example of configuring the IP address of a FortiGate interface and DHCP settings for that interface required three separate variables to be defined. However, there is a way to accomplish the same task with just one variable.
Meta Field (Variable) modifiers
The CLI Template script variables can accept modifiers to do light text transformations to the value defined under each FortiGate. From testing, it seems like this functionality can primarily be useful for variables that are in a dotted decimal IP address format. An example of this format would be the following:
192.168.100.1
Assuming that this value is assigned to a meta field (variable) called $subnet1_fgt_ip, its individual numbers delimited by the “.” can be referenced into their own field. For example:
IP Address Position | Value |
1 | 192 |
2 | 168 |
3 | 100 |
4 | 1 |
These individual fields can be referenced and modified through the use of the following syntax:
$(<meta field name>:<position>,<modifier>)
Position
The position referenced above refers to the IP address position as listed in the table above. In the case of a standard IPv4 address, there are a total of four positions and are referred to as 1, 2, 3, or 4 in the syntax.
Modifier
The modifier referenced above can refer to an addition or subtraction mathematical function or just setting the position to to a specific number. Here are the two examples of this in use:
Mathematical Function
Assuming that the meta field (variable) $subnet1_fgt_ip is set to the value “192.168.100.1”. You can use the following modifier:
$(subnet1_fgt_ip:1,+1:2,-1:3,+5:4,+10)
The resultant of the execution of this variable within a CLI Template script is the following value:
193.167.105.11
Please note that if you do not use a math operator (such as addition or subtraction), the FortiManager will just substitute the value of that positioni with the number defined in the modifier.
This does not prove to be very useful in this form, however a more practical example is to use a single variable to set the FortiGate IP address, DHCP scope start and DHCP scope end. This consolidation allows for an improved efficiency of FortiGate deployment.
Single Variable with Modifiers
A common deployment scenario with distributed FortiGates is to define a interface specific IP address and DHCP scope. This usually results in three site specific settings:
IP address of FortiGate
DHCP Start IP
DHCP End IP
Normally this would require defining three separate variables, however, with the use of variable modifiers, this can be accomplished with one variable. See below for the corresponding CLI Template snippet:
config system interface
edit "internal"
set vdom "root"
set ip $(subnet1_fgt_ip) 255.255.255.0 #1
set allowaccess ping https ssh http fgfm capwap
set type hard-switch
set stp enable
set role lan
next
end
config system dhcp server
edit 1
set dns-service default
set default-gateway $(subnet1_fgt_ip) #2
set netmask 255.255.255.0
set interface "internal"
config ip-range
edit 1
set start-ip $(subnet1_fgt_ip:4,150) #3
set end-ip $(subnet1_fgt_ip:4,200) #4
next
end
next
end
See the following explanation to this script:
set ip $(subnet1_fgt_ip) 255.255.255.0
1. Sets the IP address of the “internal” interface to “192.168.100.1”
set default-gateway $(subnet1_fgt_ip)
2. Sets the DHCP scope’s “default gateway” for the “internal” interface to “192.168.100.1”
set start-ip $(subnet1_fgt_ip:4,150)
3. Sets the DHCP scope’s starting IP address to “192.168.100.150”
set end-ip $(subnet1_fgt_ip:4,200)
4. Sets the DHCP scope’s starting IP address to “192.168.100.200”
Here’s a walk through of all of these steps completed in the FortiManager and the resultant. This will not contain all of the details as they were covered in previous blog articles.
1. Identify the FortiGates to apply the CLI Template script

2. Set the corresponding meta fields for each FortiGate


3. Create the script referencing these variables to apply to the FortiGates

4. Assign the CLI Template to all applicable FortiGates


5. Apply the configuration to each FortiGate


6. Validate the configurations on each FortiGate




Hi!
Do you have any good tips on how to deploy changes created by an external script?
Currently I have a script what creates a config which I can copy & paste directly to a Fortigate and it creates interfaces, SD-WAN, IPSec, BGP, switch & AP -config. The only way I can get this in via FortiManager is to use direct CLI -method. Is this the only way to go?
First, thanks for checking out this article! This is a great question and I assume that you are asking because you want to add a bit more automation into your process for provisioning configurations for FortiGates. For what you are looking to do, there are a few ways that come to mind to accomplish this: 1. Upload the configuration via the FortiManager’s WebGUI. This by far is the easiest and most straight forward way to get this configuration to the FortiManager. The benefit here (referring to the content in this article) is that you can build a template on the… Read more »
I was thinking about a combination of options 1&3.
Populating those meta fields by hand is a pain in the butt and FortiManager functions don’t provide enough flexibility compared to python scripts. However I was thinking that instead of generating direct configuration with python, I could just use it to create a new device with those meta fields over the API and then let FMG take care of the rest.
Thank you for the input! Also reading your articles gave me a lot of valuable insight about the possibilities and the restrictions ZTP with Fortinet. I’ll keep you posted! 🙂
That sounds like a plan. I am glad that these articles are helping. Your feedback is always welcomed and follow me on my various social media platforms for updates.
Hi! After holidays and other work stuff, it’s time to get back to the topic! Currently I have two ways of generating the ZTP-config: 1) Create ‘model device’ and populate it’s meta-fields by using Ansible This is pretty straightforward and I would pretty much suggest using this method if your configuration is simple and uniform. I’m also able to assign policy packages, system templates etc. via Ansible so this is really simple. Just provide Ansible with all data required (how to connect to FMG, device data such as serial number, subnets…) and it will take care of everything. 2) Create… Read more »
Quality feedback! Thanks!