EN 
09.03.2026 Františka WELCOME IN MY WORLD

This website is originally written in the Czech language. Most content is machine (AI) translated into English. The translation may not be exact and may contain errors.

Tento článek si můžete zobrazit v originální české verzi. You can view this article in the original Czech version.
Terraform konfigurace FortiGate s FortiOS - Firewall Policy

Terraform Configuration FortiGate with FortiOS - Firewall Policy

| Petr Bouška - Samuraj |
We will look at the options for using Terraform to automate the deployment and management of FortiGate devices. Fortinet provides a FortiOS Terraform Provider that enables management of FortiGate and FortiManager through Infrastructure as Code principles. We will demonstrate the basic connection configuration to a device and a practical example of creating a simple firewall policy using declarative configuration.
displayed: 485x (324 CZ, 161 EN) | Comments [2]

Note: The description in this article is based on Terraform version 1.14.6, FortiOS Provider version 1.24.1 and FortiGate with FortiOS 7.4.11.

HashiCorp Terraform

In previous articles in the Infrastructure as Code - Terraform series, we described the basics of using Terraform. From installation, creating a project and files, using variables, blocks for resource configuration and loading data sources, creating multiple instances of a single resource, and importing existing resources.

FortiOS Provider

We demonstrated the use of Terraform in practice with the VMware Cloud Director Provider and created objects in VMware virtualization. In this article, we will look at the FortiOS Provider and the configuration of the FortiGate system. We will build on the information described earlier and simply apply it to a different solution.

The FortiOS provider fortinetdev/fortios is currently at version 1.24. It supports FortiGate with FortiOS 6.0 or higher (6.0, 6.2, 6.4, 7.0, 7.2, 7.4, 7.6) and FortiManager 6.0 and 6.2.

Note: I am not saying (nor do I dare to judge) that Terraform is the optimal Infrastructure as Code (IaC) tool for firewall configuration. However, we have a FortiOS provider available with a large number of resources and we can use it to configure most FortiOS functions.

Terraform Project for FortiGate

We will create a folder for our project (here d:\Terraform\FortiGate), where we will store configuration files in the HCL language. We will open the folder in Visual Studio Code.

In our example, we will use the following files:

  • terraform.tf - Terraform and FortiOS Provider configuration
  • variables.tf - variable name definitions
  • terraform.tfvars - assignment of values to variables
  • main.tf - resource configuration (FortiGate settings)
  • import.tf - import of existing objects (resources)

Terraform and Provider Configuration

We will create the file terraform.tf, into which we will insert the configuration of Terraform itself and the FortiOS provider.

# Version and providers requirement
terraform {
  required_version = ">= 1.14.0"
  required_providers {
    fortios = {
      source  = "fortinetdev/fortios"
      version = "~> 1.24"
    }
  }
}

# Configure the FortiOS Provider
provider "fortios" {
  hostname = var.forti_hostname
  token    = var.forti_token
  insecure = var.forti_allow_unverified_ssl
#  vdom     = "root"
}

Authentication to FortiGate

In the provider configuration, we must use credentials with sufficient privileges. We can provide static credentials (API token or username and password) or use environment variables.

The recommended approach is to use an API token, which can be created in the FortiGate GUI:

  • (Global) > System > Administrators
  • Create New - REST API Admin
  • enter a Username for identification, select an Administrator Profile or create a new one (with minimum required privileges that are still sufficient for configuration), access can be restricted using Trusted Hosts
  • after clicking OK, the API key will be displayed — make sure to copy it (it cannot be displayed again)
FortiGate 7.4 - Administrators - New REST API Admin

Variable Definitions

To define variables, we will create a variables.tf file. 

# FortiOS variables
variable "forti_hostname" {
  description = "hostname or IP address of FortiOS unit"
  type = string
}
variable "forti_token" {
  description = "token of FortiOS unit"
  type = string
}
variable "forti_allow_unverified_ssl" {
  description = "Allow perform insecure SSL requests / unverified SSL"
  type = bool
}

Assigning Values to Variables

We will set the variable values in the terraform.tfvars file.

# Configure the FortiOS Provider
forti_hostname             = "fortigate.domain.local"
forti_token                = "xxx"
forti_allow_unverified_ssl = true

Terraform Workspace Initialization

We will use the Terraform CLI command to initialize the working directory and download the provider. In VS Code, we will use the terminal.

PS D:\Terraform\FortiGate> terraform init 
Initializing the backend...
Initializing provider plugins...
- Finding fortinetdev/fortios versions matching "~> 1.24"...
- Installing fortinetdev/fortios v1.24.1...
- Installed fortinetdev/fortios v1.24.1 (signed by a HashiCorp partner, key ID 325239133A112044)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://developer.hashicorp.com/terraform/cli/plugins/signing
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Creating a Firewall Policy

In this example, we will use Terraform to create a simple IPv4 policy on FortiGate. This is just a small demonstration of what is possible.

Policy Configuration

We will create a main.tf file in which we will define the configuration of the fortios_firewall_policy resource. This resource has a large number of arguments, so we can likely configure all options of a Firewall Policy.

# create IPv4 policy
resource "fortios_firewall_policy" "web_access" {
  name            = "Web Access to internet"
  action          = "accept"
  schedule        = "always"
  logtraffic      = "all"
  nat             = "enable"
  inspection_mode = "flow"
  status          = "enable"

  service {
    name = "HTTP"
  }
  service {
    name = "HTTPS"
  }

  srcaddr {
    name = "all"
  }

  srcintf {
    name = "LocalZone"
  }

  dstaddr {
    name = "all"
  }

  dstintf {
    name = "DMZzone"
  }
}

Applying the Terraform Configuration

Using the Terraform CLI, we will execute the operations proposed by the Terraform plan. After confirmation, a new policy will be created.

Visual Studio Code - Terraform project - Create FortiGate Policy
PS D:\Terraform\FortiGate> terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
 following symbols:
+ create

Terraform will perform the following actions:

  # fortios_firewall_policy.web_access will be created
  + resource "fortios_firewall_policy" "web_access" {
      + action                         = "accept"
      + anti_replay                    = (known after apply)

...

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

fortios_firewall_policy.web_access: Creating...
fortios_firewall_policy.web_access: Creation complete after 0s [id=104]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
FortiGate 7.4 - Policy & Objects - Firewall Policy

Configuration Error

If we make an error in the policy configuration that relates to a FortiOS setting, the apply will fail. Here, for example, an incorrect interface name that did not exist was used.

fortios_firewall_policy.web_access: Creating...

- Error: Error creating FirewallPolicy resource: Internal Server Error - Internal error when processing the request (500)
- Cli response:
- [node_check_object fail! for name LocalZone value parse error before 'LocalZone' Command fail. Return code -651]
-
-   with fortios_firewall_policy.web_access,
-   on main.tf line 47, in resource "fortios_firewall_policy" "web_access":
-   47: resource "fortios_firewall_policy" "web_access" {
Author:

Related articles:

Infrastructure as Code - Terraform

Infrastructure as Code (IaC) tools allow you to define, deploy, and manage infrastructure in a declarative (or imperative) way using configuration files. We describe the resources (servers, networks, storage, etc.) in a text file that defines the desired state. The tool ensures that the real environment matches the definition. For now, we will focus on the Terraform tool.

Fortinet FortiGate and more

Fortinet security solutions. Mostly focused on the Next Generation Firewall (NGFW) FortiGate. Configuration of FW, policies, NAT, but also VPN and authentication options. Marginally working with logs using FortiAnalyzer and with clients using FortiClient EMS.

If you want write something about this article use comments.

Comments
  1. [1] Dewpew

    Dobrý den, podařilo se Vám zjistit jak lze nastavit pořadí pravidel v policies? Me se to povedlo pouze voláním python skriptu, který to srovná, ale to je takové reseni ohejbak na ohejbak. Diky

    Wednesday, 04.03.2026 22:09 | answer
  2. [2] Samuraj

    respond to [1]Dewpew: Pořadí záznamů je velký problém. V dalším článku budu popisovat takový workaround pro DNS záznamy (ale taky to není ideální). Tu Policy jsem si jentak zkoušel a moc neřešil. Nevím také jaké pořadí tam řešíte (zda je to stejný problém jako u sub-bloků). Fortinet má takovou oficiální informaci registry.terraform.io/providers/fortinetdev/fortios/latest/docs/guides/fgt_policymove.

    Thursday, 05.03.2026 07:29 | answer
Add comment

Insert tag: strong em link

Help:
  • maximum length of comment is 2000 characters
  • HTML tags are not allowed (they will be removed), you can use only the special tags listed above the input field
  • new line (ENTER) ends paragraph and start new one
  • when you respond to a comment, put the original comment number in squar brackets at the beginning of the paragraph (line)