Files
ansible-lemp-wordpress/playbooks/lemp-wordpress-ssl.yml
Sebastian Palencsár 573224a36b 🚀 Initial release: Complete Ansible LEMP WordPress automation
 Features:
- Complete LEMP stack automation
- WordPress with WP-CLI
- Redis Object Cache (50% performance boost)
- Multi-OS support
- SSL/Let's Encrypt integration
- Security hardening
- Enterprise features
- Docker testing environment
- GitHub Actions CI/CD
- Comprehensive documentation

🧪 Fully tested and production-ready

Copyright (c) 2025 Sebastian Palencsár
2025-06-18 18:24:55 +02:00

210 lines
6.6 KiB
YAML

---
# SSL-enabled LEMP WordPress installation
- name: Install LEMP stack with WordPress and SSL
hosts: all
become: yes
vars_files:
- "../vars/{{ ansible_os_family | lower }}.yml"
vars:
# SSL Configuration
enable_ssl: "{{ enable_ssl | default(false) }}"
domain_name: "{{ domain_name | default('localhost') }}"
www_redirect: "{{ www_redirect | default(true) }}"
ssl_certificate_path: "{{ ssl_certificate_path | default('/etc/ssl/certs/' + domain_name + '.crt') }}"
ssl_certificate_key_path: "{{ ssl_certificate_key_path | default('/etc/ssl/private/' + domain_name + '.key') }}"
letsencrypt_email: "{{ letsencrypt_email | default('admin@' + domain_name) }}"
# WordPress Configuration
wordpress_path: /var/www/html
wordpress_url: "{{ 'https://' + domain_name if enable_ssl else 'http://' + domain_name }}"
# Database Configuration
mysql_root_password: "{{ mysql_root_password | default('secure_root_password_' + ansible_date_time.epoch) }}"
wordpress_db_name: "{{ wordpress_db_name | default('wordpress_db') }}"
wordpress_db_user: "{{ wordpress_db_user | default('wordpress_user') }}"
wordpress_db_password: "{{ wordpress_db_password | default('secure_wp_password_' + ansible_date_time.epoch) }}"
# WordPress Admin
wp_admin_user: "{{ wp_admin_user | default('admin') }}"
wp_admin_password: "{{ wp_admin_password | default('secure_admin_password_' + ansible_date_time.epoch) }}"
wp_admin_email: "{{ wp_admin_email | default(letsencrypt_email) }}"
wp_site_title: "{{ wp_site_title | default('My WordPress Site') }}"
tasks:
# Include base LEMP installation
- name: Include base LEMP installation tasks
include_tasks: lemp-base-tasks.yml
# SSL Certificate Management
- name: Install Certbot for Let's Encrypt
apt:
name:
- certbot
- python3-certbot-nginx
state: present
update_cache: yes
when: enable_ssl and ansible_os_family == "Debian"
tags: ssl
- name: Install Certbot for Let's Encrypt (CentOS/RHEL)
yum:
name:
- certbot
- python3-certbot-nginx
state: present
when: enable_ssl and ansible_os_family == "RedHat"
tags: ssl
- name: Check if SSL certificate exists
stat:
path: "{{ ssl_certificate_path }}"
register: ssl_cert_exists
when: enable_ssl
tags: ssl
- name: Create temporary HTTP Nginx config for Let's Encrypt
template:
src: ../templates/wordpress.nginx.j2
dest: /etc/nginx/sites-available/wordpress
when: enable_ssl and not ssl_cert_exists.stat.exists
notify: restart nginx
tags: ssl
- name: Enable temporary site
file:
src: /etc/nginx/sites-available/wordpress
dest: /etc/nginx/sites-enabled/wordpress
state: link
when: enable_ssl and not ssl_cert_exists.stat.exists
notify: restart nginx
tags: ssl
- name: Flush handlers to ensure Nginx is running
meta: flush_handlers
when: enable_ssl and not ssl_cert_exists.stat.exists
- name: Generate Let's Encrypt certificate
command: >
certbot --nginx --non-interactive --agree-tos
--email {{ letsencrypt_email }}
-d {{ domain_name }}
{% if www_redirect %}-d www.{{ domain_name }}{% endif %}
--redirect
when: enable_ssl and not ssl_cert_exists.stat.exists and domain_name != 'localhost'
tags: ssl
- name: Create self-signed certificate for localhost/testing
block:
- name: Create SSL directory
file:
path: /etc/ssl/private
state: directory
mode: '0700'
- name: Generate self-signed certificate
command: >
openssl req -x509 -nodes -days 365 -newkey rsa:2048
-keyout {{ ssl_certificate_key_path }}
-out {{ ssl_certificate_path }}
-subj "/C=US/ST=Test/L=Test/O=Test/CN={{ domain_name }}"
args:
creates: "{{ ssl_certificate_path }}"
when: enable_ssl and not ssl_cert_exists.stat.exists and domain_name == 'localhost'
tags: ssl
# Nginx Configuration
- name: Configure Nginx for WordPress with SSL
template:
src: ../templates/wordpress-ssl.nginx.j2
dest: /etc/nginx/sites-available/wordpress
backup: yes
when: enable_ssl
notify: restart nginx
tags: nginx
- name: Configure Nginx for WordPress without SSL
template:
src: ../templates/wordpress.nginx.j2
dest: /etc/nginx/sites-available/wordpress
backup: yes
when: not enable_ssl
notify: restart nginx
tags: nginx
- name: Enable WordPress site
file:
src: /etc/nginx/sites-available/wordpress
dest: /etc/nginx/sites-enabled/wordpress
state: link
notify: restart nginx
tags: nginx
- name: Remove default Nginx site
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: restart nginx
tags: nginx
# Rate limiting configuration
- name: Configure Nginx rate limiting
blockinfile:
path: /etc/nginx/nginx.conf
marker: "# {mark} ANSIBLE MANAGED BLOCK - Rate Limiting"
insertafter: "http {"
block: |
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=admin:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/m;
notify: restart nginx
tags: nginx
# WordPress Configuration
- name: Configure WordPress with SSL settings
template:
src: ../templates/wp-config.php.j2
dest: "{{ wordpress_path }}/wp-config.php"
owner: www-data
group: www-data
mode: '0600'
tags: wordpress
# SSL Auto-renewal
- name: Set up Let's Encrypt auto-renewal
cron:
name: "Renew Let's Encrypt certificates"
minute: "0"
hour: "12"
job: "/usr/bin/certbot renew --quiet"
when: enable_ssl and domain_name != 'localhost'
tags: ssl
# Firewall Configuration
- name: Configure UFW for HTTP and HTTPS
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- "80"
- "443"
when: enable_ssl
tags: firewall
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
- name: restart php-fpm
service:
name: "php{{ php_version }}-fpm"
state: restarted
- name: restart mysql
service:
name: "{{ mysql_service }}"
state: restarted