Skip to main content

rfranzen

Using Terraform to manage FortiOS

You want to manage your FortiOS device like Fortigate using a more reliable and a “zero-touch” environment. The Fortinet’s main goal with this provider, I guess, is for those who want to fully automate their environments on AWS, Azure, GCP or another cloud provider. But you can use this provider to maintain your Fortigate box as well in a very efficient way I must say.

Yeah, I know, Ansible. Maybe It’s a better way to do this kind of management with Ansible, but I just want to show you that it is possible to do it in a different way. Maybe in the future I can write a post showing how to use Ansible to manage your FortiOS or your Fortigate box.

I will just show how to make simple things. If this could be useful to you, I’m pretty sure you will easily understand the provider’s documentation to make your own configs.

But let’s go to business.

First of all, we need to use our provider. To keep things simple, let’s create a directory called “fortios”

mkdir fortios
cd fortios

Now create a file called vars.tf. We will use this file for.. of course, our variables.

vim vars.tf

And let’s define our provider and the information about our Fortigate.

terraform {
  required_providers {
    fortios = { source = “fortinetdev/fortios” }
  }
}

provider “fortios” {
  hostname = “192.168.0.1:443”  #your fortigate
  token = “your token” # wait a sec.. I will tell you how to create yours
  insecure = “true” #if you don’t want to trouble yourself with certificates. But maybe you should
}

Alright, this is what we need to start. Well, almost everything. To create your token, go to your Fortigate and create an api-user.

config system api-user
  edit "tf-admin"
    set comments "Terraform"
    set accprofile "admin_terraform"
    config trusthost
      edit 1
        set ipv4-trusthost 192.168.0.100 255.255.255.255
      next
    end
next
end

As you can see, I’ve created an api-user “admin_terraform” and this user is allowed only from the IP 192.168.0.100/32. After you create the user, an api-key will be generated.

Now, we are able to set some configs in our Fortigate. Let’s play!

Create a new file named as system.tf.

resource “fortios_system_global” “default_global” {
  hostname = “My_Fortigate”
}

resource “fortios_system_settings” “default_settings” {
  gui_advanced_polity = “enable”
  gui_allow_unnamed_policy = “enable”
  gui_dynamic_routing = “enable”
}

Well, that’s enough here. If you are used to using the FortiOS CLI, you probably know what we just did. Easy right? Let me show you how to manage your Addresses Objects.

resource “fortios_firewall_address” “PREFIX_10-8” {
  allow_routing = “disable”
  name             = “PREFIX_10/8”
  subnet           = “10.0.0.0 255.0.0.0”
  type               = “ipmask”
  visibility         = “enable”
}
resource "fortios_firewall_address" "PREFIX_172-16-12" {
  allow_routing = "disable"
  name          = "PREFIX_172.16/12"
  subnet        = "172.16.0.0 255.240.0.0"
  type          = "ipmask"
  visibility    = "enable"
}

resource "fortios_firewall_address" "PREFIX_192-168-16" {
  allow_routing = "disable"
  name          = "PREFIX_192.168/16"
  subnet        = "192.168.0.0 255.255.0.0"
  type          = "ipmask"
  visibility    = "enable"
}

resource "fortios_firewall_addrgrp" "rfc-1918" {
  allow_routing = "disable"
  color         = "26"
  exclude       = "disable"
  name          = "RFC_1918"
  type          = "folder"
  visibility    = "enable"

  member { name = fortios_firewall_address.PREFIX_10-8.name }
  member { name = fortios_firewall_address.PREFIX_172-16-12.name }
  member { name = fortios_firewall_address.PREFIX_192-168-16.name }
}

Yeah, we’ve just created three objects for our subnets and a group called RFC_1918 using them.

Now, let’s create a firewall rule just for fun.

resource “fortios_firewall_policy” “rule_01” {
  action = "accept"
  dstaddr { name = fortios_firewall_addrgrp.rfc-1918.name }
  dstaddr_negate = "enable"
  dstintf   { name = “wan1” }
  logtraffic = "all"
  name    = "LAN to WAN"
  nat = "enable"
  schedule = "always"
  service { name = "ALL" }
  srcaddr { name = fortios_firewall_address.PREFIX_192-168-16.name }
  srcintf { name = “lan1” }
  ssl_ssh_profile  = "certificate-inspection"
  utm_status       = "enable"
}

Well, I’m pretty sure if you are familiar with FortiOS CLI, you will do pretty good using Terraform.

Quick tip to use terraform (after installing it of course).

Download the provider and set everything to work.

terraform init

Check if your configuration is valid.

terraform validate

Shows the changes required to make your defined config.

terraform plan

Apply your configuration.

terraform apply

That ’s it.. thank you for reading.

FortiOS provider for Terraform

fortigate-terraform in Github

comments powered by Disqus