In the second article of the Ansible and WordPress series, we discussed the basic Ansible project structure and setting up WP-CLI and PHP. Today, I’ll walk you through creating a new database, adding a new user with correct permissions to this database, downloading WordPress with WP-CLI and configuring it properly to use our newly created database. You can find complete source code of these series at my wordpress-ansible GitHub repo.
You need to have MySQL/MariaDB as well as PHP and WP-CLI installed on your VPS server before being able to successfully execute the following tasks.
Create a new Ansible role
We need to create a new Ansible role. Let’s call it wordpress-install. Add two new folders inside the wordpress-install role folder — tasks and vars. Variables such as WordPress database user, his password, home URL and others will go into the vars/main.yml
file, while the tasks to install WordPress will go into tasks/main.yml
.
Tasks for WordPress configuration
I’ll show you all the tasks first and explain them later.
--- - name: Create WordPress database mysql_db: name="{{ wordpress_db_name }}" state=present login_user=root login_password="{{ mysql_root_password }}" - name: Create WordPress DB user and grant permissions to WordPress DB mysql_user: name="{{ wordpress_db_user }}" password="{{ wordpress_db_user_pass }}" priv="{{ wordpress_db_name }}.*:ALL" state=present login_user="root" login_password="{{ mysql_root_password }}" - name: Is WordPress downloaded? stat: path="{{ remote_wordpress_dir }}/index.php" register: wordpress_is_downloaded - name: Create WordPress directory file: path="{{ remote_wordpress_dir }}" owner="{{ remote_deploy_user }}" group="{{ remote_deploy_group }}" mode=0755 state=directory when: wordpress_is_downloaded == False - name: Download WordPress command: wp core download args: chdir: "{{ remote_wordpress_dir }}/" remote_user: "{{ remote_deploy_user }}" when: wordpress_is_downloaded == False - name: Configure WordPress command: wp core config --path="{{ remote_wordpress_dir }}" --dbname="{{ wordpress_db_name }}" --dbuser="{{ wordpress_db_user }}" --dbpass="{{ wordpress_db_user_pass }}" --dbprefix="{{ wordpress_db_prefix }}" remote_user: "{{ remote_deploy_user }}" when: wordpress_is_downloaded == False - name: Is WordPress installed? command: wp core is-installed args: chdir: "{{ remote_wordpress_dir }}/" register: wordpress_is_installed ignore_errors: True remote_user: "{{ remote_deploy_user }}" - name: Install WordPress tables command: wp core install --url="{{ wordpress_home_url }}" --title="{{ wordpress_site_title }}" --admin_user="{{ wordpress_admin_user }}" --admin_password="{{ wordpress_admin_user_pass }}" --admin_email="{{ wordpress_admin_email }}" args: chdir: "{{ remote_wordpress_dir }}/" when: wordpress_is_installed|failed remote_user: "{{ remote_deploy_user }}"
Create WordPress database
The first task is to create a new database, which will be used to store WordPress tables. Ansible comes with the mysql_db module — exactly what we need. The first parameter name=
accepts the name of the WordPress database. Let’s have it more dynamic and use a variable instead of static string. Define this variable in the vars/main.yml
file. For example
wordpress_db_name: wordpress
Parameters login_user=
and login_password=
are the credentials for authenticating with your MySQL/MariaDB database software. Define the mysql_root_password
in the vars/main.yml
file as well.
Create WordPress DB user and grant permissions to WordPress DB
In the second task, the mysql_user module is utilized. We give the user a name and password and then granting him all privileges on our newly created database on the priv="{{ wordpress_db_name }}.*:ALL"
line. The state=present
means that the user is ought to be created. If it was set to state=absent
, Ansible would remove the user from the database instead.
Is WordPress downloaded?
WP-CLI doesn’t check whether WordPress Core files are already downloaded or not. When running the Ansible tasks multiple times, the task to download WordPress produces an error. Therefore, checking if WordPress has already been downloaded or not and running the download task only if it hasn’t been is a good idea. We use a handy feature named registered variables here. Together with the stat module, we can detect if WordPress is downloaded and remember it in a variable that can be used in the following tasks.
Create WordPress directory
A simple task which creates a new directory that will hold the WordPress core files. Notice the when
clause at the end of the task. The task will be executed only if the Jinja2 expression in the when
clause evaluates to True. Exactly what we need.
Variables {{ remote_wordpress_dir }}
, {{ remote_deploy_user }}
and {{ remote_deploy_group }}
must be defined in the vars/main.yml
file. There is an example of this file at the bottom of the article.
Download WordPress
In this task, the wp
WP-CLI command line application is invoked with parameters to download the WordPress core. What’s interesting about this task is that the command module changes directory to our WordPress project directory before calling the wp
program with the help of args:
parameter. Ansible also runs the command module with a non-root user defined in the remote_deploy_user
variable. Note: you need to have this user created before Ansible can use it.
Configure WordPress
WP-CLI — being an extremely awesome tool — comes with a command to automatically configure WordPress installation for us. We just need to supply it with a few parameters and job’s done!
Is WordPress installed?
This task checks whether WordPress database tables has already been inserted into our database. Trying to insert them with WP-CLI the second time causes it to produce an error. Variable wordpress_is_installed
is registered for us here.
Install WordPress tables
Lastly, the WordPress database tables are installed with the wp core install
WP-CLI command.
when: wordpress_is_installed|failed
This when
condition utilizes a Jinja2 filter to check whether the previous task “Is WordPress installed?” failed. If it did, meaning the tables are not yet in the database, this task is run. It happens due to the fact that WP-CLI command line program exits with the status 1 (= error) when WordPress has not yet been installed.
vars/main.yml sample variables
As promised, here are some sample variables you can use in this role:
remote_deploy_user: deploy remote_deploy_group: deploy remote_deploy_home: /home/deploy remote_www_dir: "{{ remote_deploy_home}}/projects" remote_wordpress_dir: "{{ remote_www_dir }}/wordpress" wordpress_db_name: wordpress wordpress_db_user: deploy wordpress_db_user_pass: deploypass wordpress_db_prefix: wp_ wordpress_home_url: http://example.com wordpress_site_title: Test Site wordpress_admin_user: admin wordpress_admin_user_pass: adminpass wordpress_admin_email: email@example.com
What’s next?
In the final article in the Ansible and WordPress series, I’ll explain to you how to set up and configure Nginx and HHVM with Ansible. A simple WordPress production server will be finished by that time.
Awesome article; exactly what I needed. However, when I tried using your configuration, it would skip all the tasks with “when: wordpress_is_downloaded == False” which would then result in an error. The correct syntax is “when: wordpress_is_downloaded.stat.exists == False”. Thanks again!
LikeLike