...at least you're not on hold...

March 28, 2023

Automating WordPress provisioning using Ansible

Automating WordPress provisioning using Ansible

 

 

Introduction:

In this blog post, we’ll go through a detailed explanation of an Ansible script designed to set up a WordPress site running on an Nginx web server, with PHP, MySQL, and Redis deployed using Docker. This is a perfect guide for newbies who are looking to set up their own WordPress site using these technologies.

 

Let’s dive into the code and understand what each part does.

Variable File (vars/external.yml):

The script starts with a variable file that contains configuration parameters such as PHP version, domain, MySQL, and Redis settings. These parameters will be used throughout the script to configure the services.


php_version: 8.1
vhost_name: projectwp
domain: projectwp.com
mysql_mem_limit: 1024
mysql_mem_reserve: 512
mysql_root_pass: xyz
mysql_db: projectwp
mysql_user: projectwp
mysql_user_pass: xyz
redis_pass: xyz

Main Playbook (setup_server.yml):

The main playbook is responsible for running the roles defined in the script on the target host(s). It imports the variables from the external file and lists the roles to be executed in sequence.

---
- hosts: all
vars_files:
- vars/external.yml
become: yes
become_user: root
gather_facts: true
roles:
- role: update-packages
- role: install-nginx
- role: configure-nginx
- role: install-php
- role: configure-php
- role: install-wordpress
- role: install-docker
- role: setup-containers

Roles:

Ansible roles are reusable components that can be easily shared and used across different playbooks. In this script, there are several roles, each handling a specific task. Let’s go through each role and understand their purpose.

a. update-packages:

This role updates the system packages on the target host.


– name: Update system packages
apt:
name: ‘*’
state: latest


b. install-nginx:

This role installs Nginx and its dependencies, including Certbot for SSL certificates.


– name: Failsafe – disable Apache if exists
systemd:
name: apache2
state: stopped
enabled: no

– name: Install Nginx
apt:
pkg:
– nginx
– certbot
– python3-certbot-nginx

– name: Enable Nginx service
systemd:
name: nginx
daemon_reload: yes
enabled: yes
state: started

c. configure-nginx:

This role sets up the Nginx server configuration for the WordPress site, including the root directory, server name, and PHP handling.


– name: Create wwwroot
file:
path: /var/www/{{ vhost_name }}
state: directory
mode: ‘0755’

– name: Prepare config file
template:
src: files/vhost.conf.j2
dest: /etc/nginx/sites-available/web-{{ vhost_name }}.conf

– name: Create a symbolic link
file:
src: /etc/nginx/sites-available/web-{{ vhost_name }}.conf
dest: /etc/nginx/sites-enabled/web-{{ vhost_name }}.conf
state: link

– name: Restart Nginx
systemd: name: nginx
daemon_reload: yes
enabled: yes state: started


The role also uses a Jinja2 template file (vhost.conf.j2) to generate the Nginx server configuration with the appropriate variables.



d. install-php: This role installs PHP and its required extensions.


– name: Install prerequisites
apt:
pkg:
– lsb-release
– ca-certificates
– apt-transport-https
– software-properties-common

– name: Add repository
shell: add-apt-repository ppa:ondrej/php -y

– name: Install PHP
apt:
pkg:
– php{{ php_version }}
– php{{ php_version }}-cli
– php{{ php_version }}-curl
– php{{ php_version }}-mysql
– php{{ php_version }}-fpm
– php{{ php_version }}-gd
– php{{ php_version }}-xml
– php{{ php_version }}-mbstring
– php{{ php_version }}-zip
– php{{ php_version }}-soap
– php{{ php_version }}-dev


e. configure-php:

This role configures PHP settings such as memory limit, upload time, and post size.


– name: PHP ini setup
copy:
src: files/php{{ php_version }}.ini
dest: /etc/php/{{ php_version }}/cli/php.ini

– name: Increase PHP memory limit
become: true
lineinfile:
dest: /etc/php/{{ php_version }}/cli/php.ini
regexp: “memory_limit =”
line: “memory_limit = 512M”

– name: Increase PHP upload time
become: true
lineinfile:
dest: /etc/php/{{ php_version }}/cli/php.ini
regexp: “max_input_time =”
line: “max_input_time = 120”

– name: Increase PHP post size
become: true
lineinfile:
dest: /etc/php/{{ php_version }}/cli/php.ini
regexp: “post_max_size =”
line: “post_max_size = 20M”

– name: Start PHP
systemd:
name: “php{{ php_version }}-fpm”
daemon_reload: yes
enabled: yes
state: started


f. install-wordpress:

This role downloads, extracts, and sets up the WordPress site in the specified webroot directory.


– name: Download latest WP
get_url:
url: https://wordpress.org/latest.zip
dest: /tmp/latest.zip
mode: ‘0660’

– name: Extract wordpress
unarchive:
src: /tmp/latest.zip
dest: /var/www/
remote_src: yes

– name: Delete the wordpress zip
file:
state: absent
path: /tmp/latest.zip

– name: Create wwwroot
file:
path: /var/www/{{ vhost_name}}
state: directory
mode: ‘0755’

– name: Rename folder
shell: mv /var/www/wordpress/* /var/www/{{ vhost_name }}/

– name: Delete old folder
file:
path: /var/www/wordpress
state: absent

– name: Chown
become: true
shell: chown -R www-data:www-data /var/www/{{ vhost_name }}

– name: Chmod
become: true
shell: chmod -R 755 /var/www/{{ vhost_name }}


g. install-docker:

This role installs Docker and Docker Compose on the server.


– name: Install Docker prerequisites
become: true
apt:
pkg:
– gnupg
– curl

– name: Prepare keyring folder
become: true
file:
path: /etc/apt/keyrings
state: directory
mode: ‘0744’

– name: Add GPG keyring
become: true
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present

– name: Add Docker repo
become: true
apt_repository:
repo: deb https://download.docker.com/linux/ubuntu focal stable
state: present

– name: Update repository and install docker
apt:
pkg:
– docker-ce
– docker-ce-cli
– containerd.io
– docker-compose-plugin
update_cache: yes

– name: Install Docker compose
get_url:
url: https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64
dest: /usr/local/bin/docker-compose
mode: ‘u+x,g+x’


h. setup-containers:

This role sets up MySQL and Redis containers using Docker Compose, creating the necessary directories and configuration files.


– name: Create compose dir
file:
path: /opt/docker/compose-files
state: directory
mode: ‘0755’

– name: Create MySQL dirs
file:
path: /opt/docker/compose-files/mysql
state: directory
mode: ‘0755’

– name: Create MySQL dirs
file:
path: /opt/docker/mysql
state: directory
mode: ‘0755’

– name: Copy MySQL compose file
template:
src: files/mysql.j2
dest: /opt/docker/compose-files/mysql/docker-compose.yml

– name: Rise MySQL container
become: true
shell: docker-compose up -d
args:
chdir: /opt/docker/compose-files/mysql

– name: Create Redis dirs
file:
path: /opt/docker/compose-files/redis
state: directory
mode: ‘0755’

– name: Create Redis dirs
file:
path: /opt/docker/redis
state: directory
mode: ‘0755’

– name: Copy Redis compose file
template:
src: files/redis.j2
dest: /opt/docker/compose-files/redis/docker-compose.yml

– name: Rise Redis container
become: true
shell: docker-compose up -d
args:
chdir: /opt/docker/compose-files/redis

Lastly, the inventory and configuration files are defined. These files are used to specify the target server and settings for Ansible.

inventory/targets.ini

[main]
xyz.com ansible_connection=ssh ansible_ssh_port=22 ansible_ssh_user=test ansible_sudo_pass=test ansible_ssh_private_key_file=/tmp/test.key

To run the playbook, you can use the following command:

ansible-playbook -i inventory/target.ini setup_server.yml

This blog post has covered a beginner-friendly overview of an Ansible playbook designed to set up a server for hosting a WordPress website. We walked through the code structure and explained how different tasks and roles work together to create a streamlined, automated server configuration process.

In summary, this Ansible playbook:

  1. Defines external variables such as PHP version, domain name, and MySQL settings.
  2. Lists the sequence of roles to be executed during the server setup.
  3. Provides roles for updating system packages, installing and configuring Nginx, PHP, and WordPress, and setting up Docker with MySQL and Redis containers.
  4. Configures inventory and settings files for connecting to the target server.

By understanding each part of the code, you should now have a solid foundation for using and modifying this Ansible playbook for your WordPress project or other similar tasks. This playbook provides a great starting point for automating server configuration, making it easier and more efficient to set up, maintain, and scale your web applications.

Git repository : https://git.davidpetric.com/gospodar/ansible-wordpress-host-init

Posted in Linux, Software, wordpress