Since writing the article on why you should use Ansible for managing your WordPress deploys on VPS servers, I’ve added some basic configurations to my GitHub repo about this topic. In this article, we’ll be discussing how the standard Ansible project folder structure looks like and I’ll show you how to set up simple roles for PHP and WP-CLI installation on your VPS server.
Ansible project folder structure
Typical Ansible project folder structure contains these directories/files:
group_vars/ roles/ hosts playbook.yml
hosts — Ansible Inventory
This file consists of URLs of your VPS servers and custom groups which encompass those servers in logical ways.
Sample hosts file:
lamosty.com mail.lamosty.com stage.lamosty.com [webservers] lamosty.com stage.lamosty.com
If I run ansible-playbook
command with this hosts file, it will run all tasks specified in a playbook on each of those servers. The group [webservers] is used to limit which servers the tasks are executed on. More about Ansible Inventory on the official docs.
group_vars/ folder
group_vars is a folder containing variables for Ansible roles organized by groups. Taking the example hosts file with the group [webservers], the folder would have one file, named webservers in it. The contents of the webservers file are written in the YAML language.
Sample group_vars file (webservers):
# role: common remote_deploy_user: deploy remote_deploy_group: deploy remote_deploy_home: /home/deploy # role: wordpress-install 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
As you can see, data is actually stored as key-value pairs inside the file.
roles/ folder
The roles folder contains sub folders defining Ansible playbook roles. A role is a collection of tasks which will be executed on the VPS servers defined in the hosts file.
Let’s say that we have a “common” role with tasks that we want to be run in all our playbooks.
roles/ common/ tasks/ main.yml
A role folder contains another folder called tasks which is composed of YAML files with our tasks for the role.
A sample tasks YAML file:
--- # roles/common/tasks/main.yml - name: Update Apt apt: update_cache=yes
Here we define our first task called “Update Apt”. The apt module manages apt packages on Debian/Ubuntu systems. apt: update_cache=yes
means that the apt cache will be updated, the same as running sudo apt-get update command on your VPS server manually.
Roles for PHP and WP-CLI
If we want to work with WordPress sites on our VPS servers, having PHP and WP-CLI installed on them is required. As WP-CLI is a PHP script, we need to have PHP installed first.
PHP role
Inside your roles/
folder create a new one called “php”. Inside the “php” folder, create yet another new one called “tasks”. Finally, add a new YAML file called main.yml
to the “tasks” folder with following content:
--- - name: Add PHP v5.6 apt repository apt_repository: repo: 'ppa:ondrej/php5-5.6' - name: Install PHP v5.6 for WP-CLI support apt: name={{ item }} with_items: - php5 - php5-common - php5-mysqlnd - php5-mcrypt - php5-curl - php5-cli - php-pear
Let’s explain what’s going on here.
- name: Add PHP v5.6 apt repository apt_repository: repo: 'ppa:ondrej/php5-5.6'
This taks uses the apt_repository module to add a new PHP 5.6 PPA repository to our system’s sources list.
The next task — Install PHP v5.6 for WP-CLI support — uses the apt module to download and install PHP 5.6 and related libraries to our Ubuntu system. The {{ <variable_name> }}
works as string interpolation for the following with_items:
loop. On each loop, the variable item
gets the value of looped item (e.g. “php5” or “php-common”, etc) so the apt command installs all the listed items.
The equivalent to this would be to execute:
apt-get install php5 php5-common php5-mysqlnd ...
on your Ubuntu VPS server manually.
WP-CLI role
After installing PHP with required and optional libraries, we can finally download and set up WP-CLI. We’ll follow the instructions on their official page but write them in the Ansible tasks language. Analogous to the PHP role described above, we create a file called main.yml
in the roles/wp-cli/tasks/
folder with the content:
--- - name: Download WP-CLI shell: curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar - name: Make WP-CLI executable file: path: /root/wp-cli.phar mode: u=rwx,g=rx,o=rx - name: Move WP-CLI to /usr/local/bin/wp command: mv /root/wp-cli.phar /usr/local/bin/wp
The shell module executes a shell command through a shell (/bin/sh
) on the VPS server. It uses curl to download the wp-cli.phar
file.
The file module manages attributes of files, as well as their modes and other cool stuff. We just need to make the file executable so we can run it from the command line later on.
The command module behaves similarly as the shell module except it doesn’t run through the shell, so variables like $HOME
will not work. We don’t need to use a shell here, so no problem. We just move the wp-cli.phar
file into /usr/local/bin/
as wp
. This way, WP-CLI can be invoked just by running the wp
command from our VPS Ubuntu’s shell.
Putting it all together
After configuring the PHP and WP-CLI roles, we need to set up a simple Ansible playbook. Create a file called playbook.yml
in the project directory with the content:
--- - name: Installs PHP and WP-CLI with some essential software hosts: webservers remote_user: root roles: - common - php - wp-cli
As you can notice, it will be run only on the VPS servers included in the [webservers] group described in the hosts Inventory file at the beginning of the article. Tasks will be run as the root user. We want to execute tasks from the php, wp-cli andcommon roles. The common role wasn’t described in the article. It contains tasks to perform some basic tasks such as setting the locale, updating the apt cache and installing some essential software. You can inspect it in my GitHub repo.
The final project directory structure looks like this:
group_vars/ webservers roles/ common tasks main.yml php tasks main.yml wp-cli tasks main.yml hosts playbook.yml
To run the playbook, type
ansible-playbook -i hosts playbook.yml
from the command line in the project directory.
Note: you need to have your SSH Keys properly configured and added on your VPS servers for Ansible to work.
What’s next?
In the upcoming article, I’ll walk you through configuring MariaDB, Nginx and PHP-FPM Ansible roles. Stay tuned!