This project provides a GitOps approach to managing firewall configurations using Terraform modules. Network developers can define firewall rules using simple YAML configuration files, which are then automatically converted to Terraform and applied via GitLab CI/CD.
- YAML-based Configuration: Simple, human-readable firewall rule definitions
- GitOps Workflow: Version-controlled infrastructure with automated deployments
- Multi-Environment Support: Separate configurations for dev, staging, and production
- Automated Validation: YAML schema validation and Terraform plan checks
- Security Scanning: Built-in security best practices validation
- Approval Workflows: Manual approval gates for production changes
- β Palo Alto Networks (PAN-OS) - Full support for Panorama and standalone NGFW
- π§ Fortinet (planned for future release)
- π§ Check Point (planned for future release)
firewall-gitops/
βββ clusters/ # Cluster-specific configurations
β βββ example/
β βββ cluster.yaml # Cluster metadata and firewall settings
β βββ objects.yaml # Single file with all objects/addresses/services (Option 1)
β βββ objects/ # OR multiple split files (Option 2)
β βββ addresses.yaml # Address objects only
β βββ services.yaml # Service objects only
β βββ trust-zone.yaml # Rules for trust zone
β βββ dmz-zone.yaml # Rules and zone-specific objects
βββ modules/ # Terraform modules
β βββ palo-alto/ # Palo Alto Networks module
β β βββ main.tf
β β βββ variables.tf
β βββ shared/ # Shared modules and utilities
βββ terraform/ # Main Terraform configuration
β βββ main.tf # YAML parser and module calls
β βββ variables.tf
βββ scripts/ # Helper scripts
β βββ validate_yaml.py # YAML validation script
β βββ deploy.sh # Local deployment script
βββ schemas/ # JSON schemas for validation
β βββ cluster.schema.json # Cluster configuration schema
β βββ rules.schema.json # Rules configuration schema
β βββ README.md # Schema documentation
βββ docs/ # Documentation
β βββ configuration.md # Configuration guide
β βββ getting-started.md # Getting started guide
βββ requirements.txt # Python dependencies
βββ README.md
# Create cluster directory
mkdir -p clusters/my-cluster
# Copy example configurations
cp clusters/example/* clusters/my-cluster/
# Edit configurations for your environment
vim clusters/my-cluster/cluster.yaml
vim clusters/my-cluster/objects.yaml# Set up GitLab environment variables for state management
export GITLAB_PROJECT_ID="your-project-id"
export GITLAB_TOKEN="your-personal-access-token"
export GITLAB_API_URL="https://gitlab.com/api/v4"
export GITLAB_USERNAME="your-gitlab-username"# Install dependencies (use virtual environment)
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Validate YAML configuration
python scripts/validate_yaml.py# Local deployment (development)
./scripts/deploy.sh -c my-cluster -a plan
# Apply changes
./scripts/deploy.sh -c my-cluster -a apply -y- Create a feature branch for your changes
- Modify cluster configurations in YAML files
- Commit and push to GitLab
- Create a merge request - pipeline will validate automatically
- Merge to main - changes deploy automatically (with approval for production)
- Getting Started Guide - Detailed setup and usage instructions
- Configuration Guide - Complete YAML configuration reference
- Example Configurations - See
clusters/directory for working examples
- Terraform >= 1.0
- Python >= 3.8 (for validation scripts)
- Git for version control
- GitLab for CI/CD pipeline
- Palo Alto Networks: API access to Panorama or NGFW
- Permissions: Device group management (Panorama) or configuration management (NGFW)
paloaltonetworks/panos>= 2.0.5
You have two options for organizing your firewall configurations:
All addresses, services, and rules in one file:
clusters/my-cluster/
βββ cluster.yaml
βββ objects.yaml # Contains addresses, services, and rules
Split configurations across multiple files in a objects/ folder:
clusters/my-cluster/
βββ cluster.yaml
βββ objects/
βββ addresses.yaml # Just addresses
βββ services.yaml # Just services
βββ trust-zone.yaml # Rules for trust zone
βββ dmz-zone.yaml # Rules and zone-specific objects
Benefits of split configuration:
- Better organization for large rule sets
- Easier collaboration (fewer merge conflicts)
- Zone-based or team-based file separation
- Each file can contain any combination of addresses, services, and rules
- Terraform automatically merges all files during deployment
# clusters/my-cluster/objects.yaml
addresses:
- name: 'web-server'
ip_netmask: '192.168.1.100/32'
description: 'Web server address'
tags: ['web', 'server']
- name: 'app-servers'
ip_netmask: '10.1.1.0/24'
description: 'Application server subnet'
tags: ['app', 'backend']
services:
- name: 'web-service'
type: 'tcp'
destination_port: '80'
source_port: '1024-65535'
description: 'Web service HTTP'
tags: ['web', 'http']
- name: 'https-service'
type: 'tcp'
destination_port: '443'
source_port: '1024-65535'
description: 'Web service HTTPS'
tags: ['web', 'https']
rules:
- name: 'allow-web-traffic'
description: 'Allow HTTP traffic to web server'
source_zones: ['trust']
destination_zones: ['dmz']
source_addresses: ['any']
destination_addresses: ['web-server']
applications: ['web-browsing']
services: ['web-service']
action: 'allow'
log_end: true
- name: 'allow-https-traffic'
description: 'Allow HTTPS traffic to web server'
source_zones: ['trust']
destination_zones: ['dmz']
source_addresses: ['any']
destination_addresses: ['web-server']
applications: ['ssl']
services: ['https-service']
action: 'allow'
log_end: trueWhen using the objects/ folder approach, each file can contain addresses, services, or rules independently:
# clusters/my-cluster/objects/addresses.yaml
# This file contains ONLY address objects
addresses:
- name: 'web-server'
ip_netmask: '192.168.1.100/32'
description: 'Web server address'
tags: ['web', 'server']
- name: 'db-server'
ip_netmask: '192.168.2.50/32'
description: 'Database server'
tags: ['database', 'server']# clusters/my-cluster/objects/services.yaml
# This file contains ONLY service objects
services:
- name: 'web-service'
type: 'tcp'
destination_port: '80'
source_port: '1024-65535'
description: 'Web service HTTP'
tags: ['web', 'http']# clusters/my-cluster/objects/trust-zone.yaml
# This file contains ONLY rules
rules:
- name: 'allow-web-traffic'
source_zones: ['trust']
destination_zones: ['dmz']
source_addresses: ['any']
destination_addresses: ['web-server']
applications: ['web-browsing']
services: ['web-service']
action: 'allow'
log_end: true# clusters/my-cluster/objects/dmz-zone.yaml
# This file contains addresses, services, AND rules together
addresses:
- name: 'dmz-proxy'
ip_netmask: '10.0.1.10/32'
description: 'DMZ proxy server'
services:
- name: 'proxy-service'
type: 'tcp'
destination_port: '8080'
source_port: '1024-65535'
rules:
- name: 'allow-dmz-internet'
source_zones: ['dmz']
destination_zones: ['untrust']
source_addresses: ['dmz-proxy']
destination_addresses: ['any']
applications: ['web-browsing']
services: ['application-default']
action: 'allow'Note: Terraform will automatically merge all YAML files from the objects/ folder:
- All addresses from all files are combined into one list
- All services from all files are combined into one list
- All rule groups from all files are merged together
The schema supports multiple address object types based on Terraform variables:
addresses:
# IP with netmask
- name: 'subnet-example'
ip_netmask: '192.168.1.0/24'
description: 'Network subnet'
# IP range
- name: 'range-example'
ip_range: '192.168.1.10-192.168.1.20'
description: 'IP address range'
# FQDN
- name: 'domain-example'
fqdn: 'example.com'
description: 'Domain name'
# IP with wildcard mask
- name: 'wildcard-example'
ip_wildcard: '192.168.1.0/0.0.0.255'
description: 'Wildcard address'- JSON Schema Validation: Comprehensive validation using auto-generated schemas from Terraform variables
- Type Safety: Strict type checking for all configuration fields with proper null handling
- Input Validation: Regex patterns for IP addresses, ports, FQDNs, and other network objects
- Configuration Consistency: Ensures all required fields are present and valid
- Audit Trail: Full Git history of all configuration changes
- Principle of Least Privilege: Encourages minimal access patterns
The project includes comprehensive JSON schemas that are automatically generated from Terraform module variables:
- Address Objects: Support for
ip_netmask,ip_range,ip_wildcard, andfqdnwith validation - Service Objects: TCP/UDP services with port validation and source/destination port support
- Security Rules: Complete rule definitions with optional fields and security profiles
- Automatic Validation: All YAML files are validated against schemas before deployment
The GitLab CI pipeline includes:
- Validate - YAML syntax and JSON schema validation using
validate_yaml.py - Plan - Terraform plan for changed clusters
- Apply - Automated deployment (with approval for production)
- Security Scan - Security best practices validation
- Cleanup - Cleanup old plan files and artifacts
The JSON schemas are automatically generated from Terraform module variables. To regenerate schemas after updating Terraform variables:
# The schemas are based on these Terraform variables:
# - firewall_addresses (modules/palo-alto/variables.tf)
# - firewall_services (modules/palo-alto/variables.tf)
# - firewall_rules (modules/palo-alto/variables.tf)
# Validate updated schemas
source venv/bin/activate
python scripts/validate_yaml.pyThe project uses GitLab managed Terraform state with cluster-specific state names to enable independent management of multiple firewall clusters:
- All Environments: Uses GitLab managed Terraform state with naming pattern
firewall-gitops-{cluster_name} - State Storage: Terraform state is stored securely in GitLab's infrastructure
- Remote Backend: HTTP backend with GitLab's Terraform state API
Each cluster maintains its own state in GitLab, providing:
- Centralized Management: All state stored securely in GitLab
- Independent Deployments: Clusters deploy without conflicts
- Parallel Execution: Multiple clusters can be deployed simultaneously
- State Locking: GitLab provides automatic state locking
- Access Control: GitLab project permissions control state access
- Backup & Recovery: GitLab handles state backup and recovery
For local development, you need to configure GitLab access:
# Required environment variables for local development
export GITLAB_TOKEN="your-personal-access-token"
export GITLAB_API_URL="https://gitlab.com/api/v4"
export GITLAB_USERNAME="your-gitlab-username"
# Deploy using GitLab managed state
./scripts/deploy.sh -c development -a planPersonal Access Token Requirements:
- Scope:
api(for Terraform state management) - Role:
Developeror higher on the project - Find your project ID in GitLab: Project β Settings β General β Project ID
The CI/CD pipeline requires the following environment variables for PAN-OS connectivity:
Required Variables:
PANOS_HOSTNAME- Firewall or Panorama hostname/IPPANOS_USERNAME- Username for authenticationPANOS_PASSWORD- Password for authentication (or use API key)
Optional Variables:
PANOS_API_KEY- API key (alternative to username/password)PANOS_PROTOCOL- Protocol to use (default:https)PANOS_PORT- Port number (default:443)PANOS_TIMEOUT- Connection timeout in seconds (default:10)PANOS_SKIP_VERIFY_CERTIFICATE- Skip SSL verification (default:true)
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests and documentation
- Submit a merge request
This project is licensed under the MIT License - see the LICENSE file for details.
- Issues: Create an issue in GitLab for bugs or feature requests
- Documentation: Check the
docs/directory for detailed guides - Examples: Reference the
clusters/directory for working configurations