π Production-ready Ansible role for deploying and managing WordPress at scale - Enterprise-grade WordPress deployment with support for multiple cloud providers, high availability, advanced security, and comprehensive monitoring.
- Features
- Quick Start
- Requirements
- Installation
- Usage Examples
- Cloud Provider Configurations
- Advanced Configurations
- Security
- Performance Tuning
- High Availability
- Monitoring & Logging
- Backup & Recovery
- Testing
- Troubleshooting
- Contributing
- Support
- License
The stable v1 contract installs and configures WordPress end to end on Ubuntu 24.04 with Nginx and Rocky Linux 9 with Apache. CI runs the same ordered converge, idempotence, and runtime verification contract on both hosts.
A release is supported only when it is a current or LTS release, its vendor still gives it full support, and the complete Molecule contract passes. Extended phases do not count: Ubuntu ESM, Debian LTS and Enterprise Linux Maintenance Support are all out of scope.
| Release | Full support until |
|---|---|
| Enterprise Linux 9 | 2027-05-31 |
| Ubuntu 24.04 LTS | 2029-05-31 |
meta/platform_support.yml holds the policy, runtime allowlist and dates;
tests/unit/test_platform_support.py fails the build the day a release leaves
full support, or when meta/main.yml and the Molecule matrix drift from it.
When invoked through the role's standard tasks/main.yml entry point, the role
checks the same allowlist before loading distribution variables, so an unlisted
release fails before it can change packages or configuration. Direct
tasks_from invocation of internal phases is not a supported public interface.
Ubuntu 22.04 and Debian 13 remain compatibility targets, not supported release platforms. They will be promoted only after they pass the same pinned-image, end-to-end contract without platform-specific exceptions.
These features are off by default and do not currently work, because the
role references templates it does not ship (59 of them, listed in
tests/unit/missing_templates.yml):
| Flag | Missing templates |
|---|---|
wordpress_enable_monitoring |
17 |
wordpress_enable_backups |
13 |
wordpress_enable_fail2ban |
9 |
wordpress_enable_security |
9 |
wordpress_enable_caching |
6 |
wordpress_enable_ssl |
3 |
wordpress_configure_firewall |
2 |
Turning one on stops the play immediately and names the missing templates,
rather than aborting part way through and leaving the host half configured. The
shipped examples keep these flags false so they remain runnable; treat their
advanced-feature sections as topology references until the templates exist.
β Multi-Platform Support
-
Ubuntu 24.04 LTS (tested with Nginx)
-
Enterprise Linux 9 (tested on Rocky Linux 9 with Apache)
Enterprise Linux 8 is not supported: its platform Python is 3.6, below ansible-core's floor of 3.9 for a managed node, and no
python39-dnfpackage exists, so no interpreter satisfies both ansible-core and thednfmodule.
β Web Server Options
- Nginx: FastCGI cache, HTTP/2, SSL/TLS, rate limiting
- Apache: mod_php/PHP-FPM, ModSecurity WAF, HTTP/2
β PHP Support
- PHP version: 8.3 (supported upstream and exercised on every CI platform)
- OPcache optimization
- PHP-FPM tuning
- Policy-gated PHP release support
β Database Engines
- MySQL 8.0+
- MariaDB 10.6+
- Percona Server 8.0+
- External database support (RDS, Cloud SQL, Azure Database)
π’ High Availability
- Load balancer integration (HAProxy, Nginx)
- Database clustering (Galera, Group Replication)
- Shared storage (NFS, GlusterFS, Object Storage)
- Session persistence
π Security
- SSL/TLS with Let's Encrypt or custom certificates
- Web Application Firewall (ModSecurity)
- Fail2ban with WordPress-specific rules
- Security headers (HSTS, CSP, X-Frame-Options)
- File integrity monitoring
- Automated security updates
- SELinux/AppArmor support
β‘ Performance
- Redis/Memcached object caching
- FastCGI/proxy caching
- CDN integration (Cloudflare, CloudFront, Fastly)
- Image optimization (WebP, AVIF)
- Database query optimization
- HTTP/2 with Server Push
- Brotli compression
π Monitoring & Logging
- Comprehensive logging (access, error, slow query)
- Health checks and uptime monitoring
- Performance metrics collection
- Log aggregation support
- Alert notifications
βοΈ Native Cloud Integration
| Provider | Features |
|---|---|
| AWS | EC2, RDS/Aurora, ElastiCache, S3, CloudFront, Route53, SES |
| Google Cloud | Compute Engine, Cloud SQL, Memorystore, Cloud Storage, Cloud CDN |
| Microsoft Azure | VMs, Azure Database, Azure Cache, Blob Storage, Azure CDN |
| DigitalOcean | Droplets, Managed Database, Spaces, CDN |
| Cloudflare | DNS, CDN, DDoS Protection, Workers, Page Rules |
| Oracle Cloud | Compute, Autonomous Database, Object Storage |
# Install from Ansible Galaxy
ansible-galaxy install thomasvincent.wordpress_enterprise
# Clone from GitHub
git clone https://github.com/thomasvincent/ansible-wordpress-enterprise.git---
- name: Deploy WordPress
hosts: wordpress_servers
become: true
roles:
- role: thomasvincent.wordpress_enterprise
vars:
wordpress_site_url: "https://example.com"
wordpress_site_title: "My WordPress Site"
wordpress_admin_user: "admin"
wordpress_admin_email: "admin@example.com"---
- name: Production WordPress Deployment
hosts: wordpress_production
become: true
vars_files:
- vars/production.yml
- vault/secrets.yml
roles:
- role: thomasvincent.wordpress_enterprise
vars:
# Basic Configuration
wordpress_version: "6.4.2"
wordpress_site_url: "https://{{ ansible_fqdn }}"
wordpress_site_title: "Enterprise WordPress"
wordpress_environment: "production"
# Web Server & PHP
wordpress_web_server: "nginx"
wordpress_php_version: "8.3"
wordpress_php_memory_limit: "512M"
# Database
wordpress_db_engine: "mysql"
wordpress_use_external_db: true
wordpress_external_db_host: "{{ vault_db_host }}"
# Caching
wordpress_enable_redis: true
wordpress_enable_object_cache: true
# Security
wordpress_enable_ssl: true
wordpress_use_letsencrypt: true
wordpress_enable_fail2ban: true
wordpress_configure_firewall: true
# Performance
wordpress_enable_cdn: true
wordpress_cdn_provider: "cloudflare"
# Monitoring
wordpress_enable_monitoring: true
wordpress_enable_backups: true-
Control Node
- ansible-core 2.21 or higher
- Python 3.12+ (ansible-core 2.21 requires it)
-
Target Nodes
- Supported OS (see platform support)
- Python 3.9+ (ansible-core no longer supports older managed nodes)
- Sudo/root access
- Minimum 2GB RAM
- 20GB disk space
Required Ansible Collections:
ansible-galaxy collection install community.general
ansible-galaxy collection install ansible.mysql
ansible-galaxy collection install community.crypto
ansible-galaxy collection install ansible.posixPython Dependencies:
pip install -r requirements.txt# Install the role
ansible-galaxy install thomasvincent.wordpress_enterprise
# Install with specific version
ansible-galaxy install thomasvincent.wordpress_enterprise,v1.0.0
# Update to latest version
ansible-galaxy install thomasvincent.wordpress_enterprise --forceCreate requirements.yml:
---
roles:
- name: thomasvincent.wordpress_enterprise
version: v1.0.0
collections:
- name: community.general
version: ">=8.0.0"
- name: ansible.mysql
version: ">=5.0.0"
- name: community.crypto
version: ">=2.0.0"
- name: ansible.posix
version: ">=1.5.0"Install:
ansible-galaxy install -r requirements.yml# Add as submodule
git submodule add https://github.com/thomasvincent/ansible-wordpress-enterprise.git roles/wordpress_enterprise
# Update submodule
git submodule update --remote roles/wordpress_enterprise---
- name: WordPress Development Environment
hosts: localhost
connection: local
become: true
roles:
- role: wordpress_enterprise
vars:
wordpress_site_url: "http://localhost:8080"
wordpress_site_title: "Development Site"
wordpress_debug: true
wordpress_debug_log: true
wordpress_debug_display: true
wordpress_environment: "development"
# Use SQLite for development
wordpress_db_engine: "sqlite"
# Disable production features
wordpress_enable_ssl: false
wordpress_enable_fail2ban: false
wordpress_configure_firewall: false
wordpress_enable_backups: false---
- name: WordPress Staging Deployment
hosts: staging_servers
become: true
vars_files:
- vars/staging.yml
roles:
- role: thomasvincent.wordpress_enterprise
vars:
wordpress_environment: "staging"
wordpress_site_url: "https://staging.example.com"
# Enable debugging for staging
wordpress_debug: true
wordpress_debug_log: true
wordpress_debug_display: false
# Use production-like configuration
wordpress_web_server: "nginx"
wordpress_php_version: "8.3"
wordpress_enable_ssl: true
wordpress_use_letsencrypt: true
# Basic security
wordpress_enable_fail2ban: true
wordpress_configure_firewall: true
# Enable monitoring
wordpress_enable_monitoring: true---
wordpress_cloud_provider: "aws"
# EC2 Configuration
wordpress_aws_region: "us-east-1"
wordpress_aws_instance_type: "t3.medium"
# RDS Configuration
wordpress_use_external_db: true
wordpress_aws_rds_enabled: true
wordpress_external_db_host: "wordpress.cluster-xxxxx.us-east-1.rds.amazonaws.com"
wordpress_external_db_port: 3306
wordpress_external_db_name: "wordpress_prod"
wordpress_external_db_user: "{{ vault_aws_db_user }}"
wordpress_external_db_password: "{{ vault_aws_db_password }}"
wordpress_external_db_ssl_enabled: true
# ElastiCache Redis
wordpress_use_external_cache: true
wordpress_aws_elasticache_enabled: true
wordpress_redis_host: "wordpress-redis.xxxxx.cache.amazonaws.com"
wordpress_redis_port: 6379
# S3 Media Storage
wordpress_aws_s3_enabled: true
wordpress_aws_s3_bucket: "wordpress-media-prod"
wordpress_aws_s3_region: "us-east-1"
wordpress_aws_s3_access_key: "{{ vault_aws_s3_access_key }}"
wordpress_aws_s3_secret_key: "{{ vault_aws_s3_secret_key }}"
# CloudFront CDN
wordpress_aws_cloudfront_enabled: true
wordpress_aws_cloudfront_distribution_id: "EXXXXXXXXXXXXX"
wordpress_cdn_url: "https://dxxxxx.cloudfront.net"
# SES Email
wordpress_smtp_enabled: true
wordpress_smtp_provider: "ses"
wordpress_smtp_host: "email-smtp.us-east-1.amazonaws.com"
wordpress_smtp_port: 587
wordpress_smtp_user: "{{ vault_aws_ses_user }}"
wordpress_smtp_password: "{{ vault_aws_ses_password }}"---
wordpress_cloud_provider: "google"
# GCP Project
wordpress_gcp_project_id: "my-wordpress-project"
wordpress_gcp_region: "us-central1"
wordpress_gcp_zone: "us-central1-a"
# Cloud SQL
wordpress_use_external_db: true
wordpress_gcp_cloudsql_enabled: true
wordpress_gcp_cloudsql_instance: "wordpress-mysql"
wordpress_gcp_cloudsql_tier: "db-n1-standard-2"
wordpress_external_db_host: "127.0.0.1" # Via Cloud SQL Proxy
wordpress_external_db_port: 3306
wordpress_gcp_cloudsql_proxy_enabled: true
# Memorystore Redis
wordpress_use_external_cache: true
wordpress_gcp_memorystore_enabled: true
wordpress_gcp_memorystore_instance: "wordpress-redis"
wordpress_redis_host: "10.0.0.4"
wordpress_redis_port: 6379
# Cloud Storage
wordpress_gcp_storage_enabled: true
wordpress_gcp_storage_bucket: "wordpress-media-prod"
wordpress_gcp_storage_service_account_key: "{{ vault_gcp_sa_key }}"
# Cloud CDN
wordpress_gcp_cdn_enabled: true
wordpress_cdn_url: "https://cdn.example.com"
# Cloud Load Balancing
wordpress_gcp_load_balancer_enabled: true
wordpress_gcp_backend_service: "wordpress-backend"---
wordpress_cloudflare_enabled: true
wordpress_cloudflare_api_token: "{{ vault_cloudflare_api_token }}"
wordpress_cloudflare_zone_id: "{{ vault_cloudflare_zone_id }}"
wordpress_cloudflare_account_id: "{{ vault_cloudflare_account_id }}"
# DNS Management
wordpress_cloudflare_dns_records:
- name: "{{ wordpress_server_name }}"
type: "A"
value: "{{ ansible_default_ipv4.address }}"
proxied: true
- name: "www.{{ wordpress_server_name }}"
type: "CNAME"
value: "{{ wordpress_server_name }}"
proxied: true
# Security Settings
wordpress_cloudflare_security_level: "medium"
wordpress_cloudflare_ssl_mode: "full_strict"
wordpress_cloudflare_always_https: true
wordpress_cloudflare_hsts_enabled: true
wordpress_cloudflare_hsts_max_age: 31536000
# Performance
wordpress_cloudflare_cdn_enabled: true
wordpress_cloudflare_cache_level: "standard"
wordpress_cloudflare_browser_cache_ttl: 14400
wordpress_cloudflare_auto_minify:
js: true
css: true
html: true
# Page Rules
wordpress_cloudflare_page_rules:
- target: "*/wp-admin/*"
actions:
cache_level: "bypass"
security_level: "high"
- target: "*/wp-login.php"
actions:
cache_level: "bypass"
security_level: "high"
# Workers (Optional)
wordpress_cloudflare_workers_enabled: false
wordpress_cloudflare_workers_route: "*/api/*"
wordpress_cloudflare_workers_script: "wordpress-api-handler"---
wordpress_multisite_enabled: true
wordpress_multisite_type: "subdomain" # or "subdirectory"
wordpress_multisite_domain: "example.com"
wordpress_multisite_sites:
- domain: "blog.example.com"
title: "Company Blog"
admin_email: "blog@example.com"
- domain: "shop.example.com"
title: "Online Store"
admin_email: "shop@example.com"---
# PHP Version Management
wordpress_php_version: "8.3"
wordpress_php_versions_available:
- "8.3"
# PHP-FPM Pool Configuration
wordpress_php_fpm_pm: "dynamic"
wordpress_php_fpm_max_children: 50
wordpress_php_fpm_start_servers: 5
wordpress_php_fpm_min_spare_servers: 5
wordpress_php_fpm_max_spare_servers: 35
wordpress_php_fpm_max_requests: 500
# PHP Settings
wordpress_php_memory_limit: "512M"
wordpress_php_max_execution_time: 300
wordpress_php_max_input_time: 300
wordpress_php_max_input_vars: 5000
wordpress_php_upload_max_filesize: "256M"
wordpress_php_post_max_size: "256M"
# OPcache Settings
wordpress_opcache_enable: true
wordpress_opcache_memory: 256
wordpress_opcache_max_files: 10000
wordpress_opcache_validate_timestamps: 0 # 0 for production
wordpress_opcache_revalidate_freq: 0---
# MySQL/MariaDB Tuning
wordpress_mysql_innodb_buffer_pool_size: "1G"
wordpress_mysql_innodb_log_file_size: "256M"
wordpress_mysql_innodb_flush_method: "O_DIRECT"
wordpress_mysql_innodb_file_per_table: true
wordpress_mysql_query_cache_size: "128M"
wordpress_mysql_query_cache_type: 1
wordpress_mysql_max_connections: 500
wordpress_mysql_thread_cache_size: 50
wordpress_mysql_table_open_cache: 4000
# Slow Query Logging
wordpress_mysql_slow_query_log: true
wordpress_mysql_slow_query_log_file: "/var/log/mysql/slow-query.log"
wordpress_mysql_long_query_time: 2
# Database Maintenance
wordpress_db_optimize_schedule: "weekly"
wordpress_db_backup_before_optimize: true---
# WordPress Security
wordpress_disable_file_edit: true
wordpress_disable_file_mods: false
wordpress_force_ssl_admin: true
wordpress_disable_xmlrpc: true
wordpress_disable_rest_api_public: true
# File Permissions
wordpress_secure_file_permissions: true
wordpress_files_owner: "www-data"
wordpress_files_group: "www-data"
wordpress_files_mode: "0644"
wordpress_dirs_mode: "0755"
# Security Headers
wordpress_security_headers:
- name: "X-Frame-Options"
value: "SAMEORIGIN"
- name: "X-Content-Type-Options"
value: "nosniff"
- name: "X-XSS-Protection"
value: "1; mode=block"
- name: "Referrer-Policy"
value: "strict-origin-when-cross-origin"
- name: "Content-Security-Policy"
value: "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval'"
# Fail2ban Configuration
wordpress_fail2ban_enabled: true
wordpress_fail2ban_maxretry: 5
wordpress_fail2ban_findtime: "10m"
wordpress_fail2ban_bantime: "1h"
wordpress_fail2ban_ignoreips:
- "127.0.0.1/8"
- "192.168.0.0/16"
# ModSecurity WAF (Apache only)
wordpress_modsecurity_enabled: true
wordpress_modsecurity_ruleset: "OWASP CRS 3.3"
wordpress_modsecurity_custom_rules: []
# File Integrity Monitoring
wordpress_aide_enabled: true
wordpress_aide_email: "security@example.com"
wordpress_aide_schedule: "daily"---
# Certificate Management
wordpress_ssl_provider: "letsencrypt" # or "custom", "self-signed"
wordpress_ssl_cert_path: "/etc/ssl/certs/{{ wordpress_server_name }}.crt"
wordpress_ssl_key_path: "/etc/ssl/private/{{ wordpress_server_name }}.key"
# Let's Encrypt
wordpress_letsencrypt_email: "{{ wordpress_admin_email }}"
wordpress_letsencrypt_staging: false
wordpress_letsencrypt_webroot: "/var/www/letsencrypt"
# SSL Configuration
wordpress_ssl_protocols: "TLSv1.2 TLSv1.3"
wordpress_ssl_ciphers: >-
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
wordpress_ssl_prefer_server_ciphers: true
wordpress_ssl_session_cache: "shared:SSL:50m"
wordpress_ssl_session_timeout: "1d"
wordpress_ssl_stapling: true
wordpress_ssl_stapling_verify: true
# HSTS
wordpress_hsts_enabled: true
wordpress_hsts_max_age: 31536000
wordpress_hsts_include_subdomains: true
wordpress_hsts_preload: true---
# Object Caching
wordpress_object_cache_provider: "redis" # or "memcached"
wordpress_redis_maxmemory: "512mb"
wordpress_redis_maxmemory_policy: "allkeys-lru"
wordpress_redis_databases: 16
wordpress_redis_timeout: 5
wordpress_redis_persistent: true
# Page Caching (Nginx)
wordpress_fastcgi_cache_enabled: true
wordpress_fastcgi_cache_size: "256m"
wordpress_fastcgi_cache_inactive: "60m"
wordpress_fastcgi_cache_valid: "60m"
wordpress_fastcgi_cache_methods: ["GET", "HEAD"]
wordpress_fastcgi_cache_bypass_cookies:
- "wordpress_logged_in_"
- "wp-postpass_"
- "wordpress_no_cache"
# Browser Caching
wordpress_browser_cache_enabled: true
wordpress_browser_cache_max_age: 31536000
wordpress_browser_cache_types:
- "image/jpeg"
- "image/png"
- "image/gif"
- "image/webp"
- "image/svg+xml"
- "text/css"
- "application/javascript"
- "font/woff2"---
# CDN Configuration
wordpress_cdn_enabled: true
wordpress_cdn_provider: "cloudflare" # or "cloudfront", "fastly", "bunnycdn"
wordpress_cdn_url: "https://cdn.example.com"
wordpress_cdn_push_enabled: true
# Asset Optimization
wordpress_cdn_minify_html: true
wordpress_cdn_minify_css: true
wordpress_cdn_minify_js: true
wordpress_cdn_combine_css: false
wordpress_cdn_combine_js: false
# Image Optimization
wordpress_cdn_image_optimization: true
wordpress_cdn_webp_enabled: true
wordpress_cdn_avif_enabled: true
wordpress_cdn_lazy_load: true
wordpress_cdn_responsive_images: true---
wordpress_ha_enabled: true
wordpress_ha_load_balancer: "haproxy" # or "nginx"
# Backend Servers
wordpress_ha_backends:
- name: "web1"
address: "10.0.1.10:80"
weight: 1
max_connections: 100
- name: "web2"
address: "10.0.1.11:80"
weight: 1
max_connections: 100
- name: "web3"
address: "10.0.1.12:80"
weight: 1
max_connections: 100
# Health Checks
wordpress_ha_health_check_interval: 2000
wordpress_ha_health_check_timeout: 5000
wordpress_ha_health_check_retries: 3
wordpress_ha_health_check_uri: "/health"
# Session Persistence
wordpress_ha_session_persistence: true
wordpress_ha_session_cookie: "SERVERID"
wordpress_ha_session_storage: "redis" # Shared session storage---
# Galera Cluster (MariaDB)
wordpress_db_cluster_enabled: true
wordpress_db_cluster_type: "galera"
wordpress_db_cluster_nodes:
- host: "db1.example.com"
port: 3306
- host: "db2.example.com"
port: 3306
- host: "db3.example.com"
port: 3306
wordpress_db_cluster_sst_method: "rsync"
wordpress_db_cluster_wsrep_provider: "/usr/lib/galera/libgalera_smm.so"
# ProxySQL for connection pooling
wordpress_proxysql_enabled: true
wordpress_proxysql_admin_password: "{{ vault_proxysql_admin_password }}"
wordpress_proxysql_monitor_password: "{{ vault_proxysql_monitor_password }}"---
# Monitoring Tools
wordpress_monitoring_provider: "prometheus" # or "datadog", "newrelic"
# Prometheus Exporters
wordpress_prometheus_node_exporter: true
wordpress_prometheus_mysql_exporter: true
wordpress_prometheus_nginx_exporter: true
wordpress_prometheus_php_fpm_exporter: true
# Health Checks
wordpress_health_check_enabled: true
wordpress_health_check_path: "/health"
wordpress_health_check_response: "OK"
# Custom Metrics
wordpress_custom_metrics:
- name: "wordpress_posts_total"
query: "SELECT COUNT(*) FROM wp_posts WHERE post_status = 'publish'"
- name: "wordpress_users_total"
query: "SELECT COUNT(*) FROM wp_users"
- name: "wordpress_comments_total"
query: "SELECT COUNT(*) FROM wp_comments WHERE comment_approved = '1'"---
# Log Management
wordpress_log_aggregator: "elasticsearch" # or "splunk", "cloudwatch"
wordpress_log_level: "info"
wordpress_log_format: "json"
# Log Paths
wordpress_logs_dir: "/var/log/wordpress"
wordpress_access_log: "{{ wordpress_logs_dir }}/access.log"
wordpress_error_log: "{{ wordpress_logs_dir }}/error.log"
wordpress_debug_log: "{{ wordpress_logs_dir }}/debug.log"
# Log Rotation
wordpress_logrotate_enabled: true
wordpress_logrotate_frequency: "daily"
wordpress_logrotate_retention: 30
wordpress_logrotate_compress: true
# Audit Logging
wordpress_audit_log_enabled: true
wordpress_audit_log_events:
- "user_login"
- "user_logout"
- "post_published"
- "plugin_activated"
- "theme_changed"---
# Backup Settings
wordpress_backup_enabled: true
wordpress_backup_dir: "/var/backups/wordpress"
wordpress_backup_retention_days: 30
wordpress_backup_compression: "gzip"
# Backup Schedule
wordpress_backup_schedule:
- type: "full"
frequency: "weekly"
day: "sunday"
hour: 2
- type: "incremental"
frequency: "daily"
hour: 3
# Backup Destinations
wordpress_backup_destinations:
- type: "local"
path: "/var/backups/wordpress"
- type: "s3"
bucket: "wordpress-backups"
region: "us-east-1"
access_key: "{{ vault_aws_backup_access_key }}"
secret_key: "{{ vault_aws_backup_secret_key }}"
- type: "rsync"
host: "backup.example.com"
path: "/backups/wordpress"
ssh_key: "/root/.ssh/backup_rsa"
# Backup Verification
wordpress_backup_verify: true
wordpress_backup_test_restore: true
wordpress_backup_notification_email: "admin@example.com"---
# Disaster Recovery Plan
wordpress_dr_enabled: true
wordpress_dr_site: "dr.example.com"
wordpress_dr_sync_interval: "15m"
# Recovery Time Objective (RTO)
wordpress_dr_rto_hours: 4
# Recovery Point Objective (RPO)
wordpress_dr_rpo_minutes: 15
# Automated Failover
wordpress_dr_auto_failover: false
wordpress_dr_health_check_failures: 3
wordpress_dr_notification_channels:
- "email:ops@example.com"
- "slack:#incidents"
- "pagerduty:service-key"# Enable WordPress debugging
wordpress_debug: true
wordpress_debug_log: true
wordpress_debug_display: true
# Check PHP errors
wordpress_php_display_errors: true
wordpress_php_error_reporting: "E_ALL"# Test database connectivity
ansible wordpress_servers -m mysql_info -a "login_host={{ wordpress_db_host }} login_user={{ wordpress_db_user }} login_password={{ wordpress_db_password }}"
# Check database variables
ansible wordpress_servers -m mysql_variables -a "variable=max_connections"# Enable query monitoring
wordpress_mysql_slow_query_log: true
wordpress_mysql_long_query_time: 1
# Enable performance profiling
wordpress_newrelic_enabled: true
wordpress_newrelic_app_name: "WordPress Production"
wordpress_newrelic_license_key: "{{ vault_newrelic_license }}"# Safe mode - disable all plugins
wordpress_safe_mode: true
wordpress_disabled_plugins:
- "problematic-plugin"
- "conflicting-plugin"# Check WordPress installation
ansible wordpress_servers -m command -a "wp core verify-checksums --path={{ wordpress_path }}"
# List active plugins
ansible wordpress_servers -m command -a "wp plugin list --status=active --path={{ wordpress_path }}"
# Check database status
ansible wordpress_servers -m command -a "wp db check --path={{ wordpress_path }}"
# Clear cache
ansible wordpress_servers -m command -a "wp cache flush --path={{ wordpress_path }}"
# Run WordPress cron
ansible wordpress_servers -m command -a "wp cron run --path={{ wordpress_path }}"---
# Apache Bench Testing
wordpress_benchmark_ab_requests: 1000
wordpress_benchmark_ab_concurrency: 100
# Siege Testing
wordpress_benchmark_siege_users: 50
wordpress_benchmark_siege_time: "5M"
# Custom Test URLs
wordpress_benchmark_urls:
- "/"
- "/shop/"
- "/blog/"
- "/api/v1/posts"---
# Target Metrics
wordpress_performance_targets:
page_load_time: 2.0 # seconds
time_to_first_byte: 0.5 # seconds
requests_per_second: 100
concurrent_users: 500
uptime_percentage: 99.9---
wordpress_plugins:
# Security
- name: "wordfence"
version: "latest"
activate: true
config:
scan_schedule: "daily"
firewall_mode: "extended"
# Performance
- name: "wp-rocket"
version: "3.15"
activate: true
license_key: "{{ vault_wp_rocket_license }}"
# SEO
- name: "wordpress-seo"
version: "latest"
activate: true
config:
enable_xml_sitemap: true
enable_schema: true
# Backup
- name: "updraftplus"
version: "latest"
activate: true
config:
backup_schedule: "daily"
remote_storage: "s3"---
wordpress_themes:
- name: "twentytwentyfour"
version: "latest"
activate: false
- name: "custom-theme"
source: "https://example.com/themes/custom-theme.zip"
activate: true
wordpress_child_theme:
parent: "custom-theme"
name: "custom-theme-child"
activate: trueThe default Molecule scenario is the release contract: Ubuntu 24.04/Nginx and Rocky Linux 9/Apache must converge, be idempotent, and pass runtime checks.
# Install testing dependencies
mise exec python@3.12 -- python -m pip install -r requirements.txt
mise exec python@3.12 -- ansible-galaxy collection install -r requirements.yml
# Run the complete release contract
mise exec python@3.12 -- molecule test --scenario-name default
# Interactive testing
mise exec python@3.12 -- molecule converge --scenario-name default
mise exec python@3.12 -- molecule idempotence --scenario-name default
mise exec python@3.12 -- molecule verify --scenario-name default
mise exec python@3.12 -- molecule destroy --scenario-name default| Scenario | Platforms | Purpose |
|---|---|---|
| default | Ubuntu 24.04/Nginx, Rocky Linux 9/Apache | Stable release contract |
All scenarios include:
- β Syntax checking
- β Role deployment
- β Idempotency verification
- β Comprehensive validation tests
π For detailed testing documentation, see TESTING.md
---
# Test configuration in tests/integration/playbook.yml
- name: Test WordPress Installation
hosts: test_servers
tasks:
- name: Check WordPress is accessible
uri:
url: "https://{{ wordpress_site_url }}"
status_code: 200
- name: Verify database connection
command: wp db check --path={{ wordpress_path }}
become_user: "{{ wordpress_system_user }}"
- name: Test admin login
uri:
url: "https://{{ wordpress_site_url }}/wp-login.php"
method: POST
body_format: form-urlencoded
body:
log: "{{ wordpress_admin_user }}"
pwd: "{{ wordpress_admin_password }}"
status_code: 302# Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/ansible-wordpress-enterprise.git
cd ansible-wordpress-enterprise
# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install development dependencies
pip install -r requirements-dev.txt
# Install pre-commit hooks
pre-commit install
# Run tests
molecule test
# Run linters
ansible-lint
yamllint .We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Documentation: Wiki
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Security: Report security vulnerabilities to security@example.com
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Thomas Vincent
- GitHub: @thomasvincent
- Email: thomasvincent@users.noreply.github.com
- WordPress Community
- Ansible Community
- Cloud Provider Documentation Teams
- All contributors to this project
Made with β€οΈ by the open source community
β Star this project if you find it helpful!