Backup FortiOS config with Ansible – with RestAPI

In the previous post, I demonstrated how to get the fortigate configuration using Ansible with fortios module. In this post, I will show you how to get the backup config using Ansible with RestAPI via uri module.

Here’s pros and cons compared to fortios module:

pros

  • Not dependent on external module, which may be outdated/not maintained
  • Access right is more developer friendly — it’s based on API token, which can be expired/regenerate on demand.

cons

  • Not fully integrated with Ansible — you need to have a knowledge on FortiOS RestAPI to call them

Differences compared to fortios module generated backup, which might be or might not be important in your use case.

  • uuid, snmp-index are not redacted in the config
  • double quotation is not redacted in the config

1. Create API user and generate API key on Fortigate

Please refer my previous post “Fortigate RestAPI config backup – FortiOS” and generate API key.

2. Configure Ansible inventory and playbook

In your Ansible environment, configure inventory file. In my case, I just use default file in /etc/ansible/hosts for demonstration purpose. API_token is specific to each device, so it is registered as an individual variable.

$ cat hosts

[fortigate]
x.x.x.x access_token=w4q9qtfbGry3Nbc40kHjsk9mxG****
y.y.y.y access_token=tfy8c9b8Nxw6N3Q5Q5bg9z69dn****

In playbook, I use uri module to retrieve the config, and use copy to write the content into the local file. In my example below, I backup all the configuration, but you can change scope(vdom) or any other parameter to suite your needs. I’m gathering facts simply because I need to use ansible_date_time variable, you can disable fact gathering and save a few seconds per run if you don’t need these variable appended in your config.

$ cat fortigate_backup.yml 
- name: fortigate config backup
  connection: local
  hosts: fortigate

  tasks:
    - name: get current config
      uri:
        url: 'https://{{ ansible_host }}/api/v2/monitor/system/config/backup/?scope=global&access_token={{ access_token }}'
        return_content: yes
        validate_certs: no
      register: current_config

    - name: write config to local file
      local_action: copy content={{ current_config.content }} dest=./{{ inventory_hostname }}_{{ ansible_date_time.date }}.txt

3. Test

Once it’s configured, you can just run the playbook.

$ ansible-playbook fortigate_backup.yml 

PLAY [fortigate config backup] *******************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************
ok: [x.x.x.x]
ok: [y.y.y.y]

TASK [get current config] ************************************************************************************************************************************************************
ok: [x.x.x.x]
ok: [y.y.y.y]

TASK [write config to local file] ****************************************************************************************************************************************************
changed: [x.x.x.x -> localhost]
changed: [y.y.y.y -> localhost]

PLAY RECAP ***************************************************************************************************************************************************************************
x.x.x.x               : ok=3    changed=1    unreachable=0    failed=0   
y.y.y.y               : ok=3    changed=1    unreachable=0    failed=0   

Now you should have backup file where you specified in the playbook. In my case, I got two backup config in the same directory as the playbook. And of course it correctly parses the Non-Ascii characters.