The integration of Ansible into the management of Fortinet FortiGate firewalls represents a fundamental shift from manual, chassis-by-chassis configuration to a modern Infrastructure as Code (IaC) paradigm. In enterprise environments where the number of security appliances scales beyond a handful of devices, the traditional method of navigating the FortiOS web user interface becomes a significant operational bottleneck. The repetitive nature of applying identical policy changes, updating address objects, or managing certificates across multiple firewalls introduces human error and operational latency. By leveraging the specialized FortiOS collection for Ansible, administrators can automate nearly every aspect of firewall management, transforming tedious manual tasks into repeatable, version-controlled playbooks. This transition allows for the rapid provisioning and configuration of multiple FortiGates simultaneously, ensuring consistency across the security fabric and drastically reducing the time required for deployment.
Architectural Foundations of FortiGate Automation
To achieve automation, the relationship between the Ansible control node and the FortiGate target must be established through specific communication protocols and authentication mechanisms. The FortiOS environment is designed to be programmable, allowing Ansible to interact with the device via the HTTP API, which is the preferred method for the fortinet.fortios collection.
Authentication Modalities
FortiOS provides two primary methods for authenticating Ansible sessions. The choice between these methods often depends on the security requirements of the organization and the specific stage of the device lifecycle.
- User-Based Authentication: This method utilizes the
ansible_userandansible_passwordvariables. It mimics a standard administrative login. While straightforward, it requires the management of plaintext or encrypted passwords within the Ansible vault or inventory. - Token-Based Authentication: This method employs the
fortios_access_token. API tokens provide a more secure and streamlined way to authenticate, as they can be scoped to specific permissions and do not require the transmission of the administrative password during every session.
The use of these credentials must be explicitly defined within the YAML configuration or the inventory file to ensure that the Ansible control node can establish a secure session with the FortiOS API.
The Role of the HTTP API
While SSH is a common management protocol, Ansible's interaction with FortiGate primarily relies on the httpapi connection. This is configured through the ansible_connection=httpapi variable. By utilizing the REST API, Ansible can send structured requests to the firewall, which is more efficient and reliable for configuration tasks than parsing CLI output. To ensure connectivity, administrators often set ansible_httpapi_use_ssl=yes to encrypt the traffic, while ansible_httpapi_validate_certs=no is frequently used in lab or internal environments where self-signed certificates are present and would otherwise cause the connection to fail.
Installation and Environment Setup
The deployment of an Ansible-ready environment requires a Linux-based control node. The process involves installing the core Ansible engine, the specific Fortinet collections, and the necessary Python libraries to facilitate communication.
Core Ansible Installation
The installation process begins with updating the package manager to ensure the latest versions of dependencies are retrieved. The following commands are executed on a Debian-based system:
apt-get update
apt-get -y install ansible
It is critical that these commands are executed by the root user. If the current session is not root, the user must be added to the sudoers list to grant the necessary permissions for system-level package installation.
Collection and Library Deployment
Once the core engine is active, the specific modules for FortiOS must be installed from Ansible Galaxy. This collection contains the logic required to translate Ansible playbooks into FortiOS API calls.
ansible-galaxy collection install fortinet.fortios
In addition to the collection, a Python library is required for the underlying API communication. This is handled via the Python package manager:
pip install fortiosapi
The combination of the fortinet.fortios collection and the fortiosapi library creates the full stack necessary for the control node to manage the lifecycle of a FortiGate device.
Inventory Management and Variable Configuration
The inventory file is the central directory where Ansible stores the mapping of target devices and their associated connection variables. This file informs Ansible which devices to target and how to talk to them.
Creating the Inventory File
Administrators can use standard Linux text editors such as nano or vim to create the inventory file. For instance, using nano <file name> allows for a quick setup. When using nano, the user must press Ctrl + X to save and exit, at which point the editor will prompt for the directory path to confirm the file location.
Defining the Host Structure
The inventory is organized into groups and variables. A standard configuration for multiple FortiGates is structured as follows:
| Section | Variable | Purpose |
|---|---|---|
[fortigates] |
ansible_host |
The IP address of the FortiGate device |
[fortigates] |
ansible_user |
The administrative username |
[fortigates] |
ansible_password |
The administrative password |
[fortigates] |
fortios_access_token |
The API token for token-based auth |
[fortigates:vars] |
ansible_network_os |
Set to fortinet.fortios.fortios |
[all:vars] |
ansible_connection |
Set to httpapi |
[all:vars] |
ansible_httpapi_use_ssl |
Set to yes for encrypted traffic |
[all:vars] |
ansible_httpapi_validate_certs |
Set to no to bypass cert validation |
Example Inventory Implementation
A fully realized inventory file would appear as follows:
```text
[fortigates]
fgt ansiblehost=
fortigate ansible
[fortigates:vars]
ansiblenetworkos=fortinet.fortios.fortios
[all:vars]
ansibleconnection=httpapi
ansiblehttpapivalidatecerts=no
ansiblehttpapiuse_ssl=yes
```
Playbook Development and Execution
Playbooks are the heart of Ansible, written in YAML format to describe the desired state of the network device. Because YAML is strictly space-sensitive, the use of the Tab key is forbidden; only spaces should be used to define layers, as tabs will trigger syntax errors.
Task Integration
Playbooks can be organized by including separate task files for different operational needs. This modularity allows administrators to maintain a library of common tasks and call them as needed.
yaml
tasks:
- include_tasks: file1_get_policy.yml
- include_tasks: file2_get_address.yml
The include_tasks module allows for the separation of concerns, where file1_get_policy.yml might handle firewall policy retrieval and file2_get_address.yml handles address object management.
Executing the Playbook
Once the inventory and YAML files are prepared, the playbook is executed using the ansible-playbook command. The command structure requires the specification of the inventory file and the playbook file:
ansible-playbook -i <variable text file name> < YAML file name>
This command triggers the control node to parse the inventory, establish connections via the HTTP API, and execute the tasks defined in the YAML file against the target FortiGate devices.
Advanced Implementation Scenarios
Beyond basic configuration, Ansible can be used to solve complex deployment hurdles, such as initial device provisioning and certificate management.
Zero-Touch Initial Configuration
A common challenge with brand-new FortiGate devices is the mandatory initial admin password change, which typically requires manual intervention and breaks the "zero-touch" deployment goal. To bypass this, an administrator can define the initial state in the inventory and a specific variable for the new password.
In the inventory:
```text
[fortigates]
fortigatepr ansiblehost=192.168.1.99 ansibleuser="admin" ansiblepassword=""
[fortigates:vars]
ansiblenetworkos=fortinet.fortios.fortios
fortigateadminpassword="password123"
```
By setting the ansible_password to an empty string for the initial connection and providing the fortigate_admin_password as a variable, the automation script can target the initial setup phase of the device.
Certificate Management and Integration
Managing SSL/TLS certificates on FortiGate devices is often a complex task. For those using a Secure Web Application Gateway (SWAG) with Certbot (an Nginx reverse-proxy and certificate manager), a hybrid automation workflow can be established.
The process involves:
- Using Ansible to rsync generated certificates from a Docker-mounted SWAG volume to a local folder on the Ansible host.
- Using Ansible modules to upload these certificates from the local host to the FortiGate device.
- Enabling certificate visibility on the FortiGate via the admin interface under System > Feature Visibility.
This ensures that certificates are renewed automatically by Certbot and propagated to the firewall without manual upload and import processes.
Technical Specifications and Requirements
The following table summarizes the technical requirements for a successful FortiGate-Ansible integration.
| Requirement | Specification | Note |
|---|---|---|
| Control Node OS | Linux (Debian-based recommended) | Required for apt-get and Ansible core |
| FortiOS Version | v7.0.3 and above (documented) | Compatibility varies by collection version |
| Connection Type | httpapi |
Mandatory for fortinet.fortios collection |
| Required Python Lib | fortiosapi |
Essential for API communication |
| Collection | fortinet.fortios |
Available via Ansible Galaxy |
| Hardware Example | FortiWifi 60E | Validated for these configurations |
| YAML Format | Space-delimited (No Tabs) | Strict syntax requirement |
Conclusion: Analytical Review of FortiGate Automation
The transition from manual GUI-based management to Ansible-driven orchestration provides a scalable framework for network security. The primary technical advantage lies in the abstraction of the FortiOS API, which allows for the programmatic manipulation of firewall policies, address objects, and system settings.
The dual-authentication approach (User vs. Token) allows administrators to balance ease of setup with high-security requirements. While the initial setup—including the installation of the fortiosapi library and the fortinet.fortios collection—requires a specific sequence of commands, the long-term benefit is a reduction in configuration drift. By defining the firewall state in YAML, the "source of truth" moves from the device itself to a version-controlled repository.
Furthermore, the ability to overcome "day-zero" configuration hurdles, such as the initial admin password change and the automated deployment of certificates via SWAG and rsync, demonstrates that Ansible can extend beyond simple configuration into full-lifecycle management. The shift to an httpapi connection, combined with the disabling of certificate validation for internal nodes, allows for a flexible yet secure deployment path. Ultimately, the integration of Ansible with FortiGate transforms the firewall from a standalone appliance into a manageable component of a larger, automated infrastructure ecosystem.