How To Install/Setup/Deploy/Configure WordPress Using Ansible on AWS EC2 Linux/Ubuntu Server

In this tutorial, we are going to learn how to install WordPress on Linux/Ubuntu Using Ansible.

Following are the pre-requisites:
1. A Workstation having Ansible installed
2. An AWS account and EC2 instance (Ubuntu Instance)
3. SSH access to EC2 instance

Video Tutorial

Create Following Playbook and Roles:

1. First we need to create a directory where we can store all of our configurations:

$ mkdir ansible-demo
$ cd ansible-demo
$ mkdir roles
$ touch hosts
$ touch playbook.yml

2. Next, we will open up the hosts file and add the desired name along with the IP address(es) of the server(s) where WordPress will be installed in the following format:

[wordpress]
wp_server_ip

3. After this we will define the different roles in the roles sub-directory:

$ cd roles
$ ansible-galaxy init server
$ ansible-galaxy init php
$ ansible-galaxy init mysql
$ ansible-galaxy init wordpress

2. Creating Roles

Ansible instructions are written in .yml files which are quite human-readable.

We will write for each individual role of the LAMP stack and WordPress build on top of it.

1. Playbook.yml

First, add the following contents into the file ansible-demo/playbook.yml

- hosts: all
  gather_facts: False

tasks:
  - name: install python 2
    raw: test -e /usr/bin/python || (apt -y update && apt    install -y python-minimal)

- hosts: wordpress

  roles:
    - server
    - php
    - mysql
    - wordpress

This installs Python 2.7 onto all the target servers and assigns four roles to the hosts.

2. Server Role

We will add the following contents into the file ansible-demo/roles/server/tasks/main.yml

# tasks file for server
- name: Update apt cache
  apt: update_cache=yes cache_valid_time=3600
  become: yes

- name: Install required software
  apt: name={{ item }} state=present
  become: yes
  with_items:
    - apache2
    - mysql-server
    - php7.2-mysql
    - php7.2
    - libapache2-mod-php7.2  
    - python-mysqldb

3. PHP

Here we will install additional PHP modules that write the following contents to the file ansible-demo/roles/php/tasks/main.yml

# tasks file for php
- name: Install php extensions
  apt: name={{ item }} state=present
  become: yes
  with_items:
    - php7.2-gd
    - php7.2-ssh2

4. MySQL

Next, we will add the following contents into the file  ansible-demo/roles/mysql/defaults/main.yml

# defaults file for mysql
wp_mysql_db: wordpress
wp_mysql_user: wordpress
wp_mysql_password: randompassword

After this, we configure our main MySQL task of creating a MySQL user, database and granting that user access to the newly created database.
In the file, ansible-demo/roles/mysql/tasks/main.yml add the following:

- name: Create mysql database
  mysql_db: name={{ wp_mysql_db }} state=present
  become: yes

- name: Create mysql user
  mysql_user:
  name={{ wp_mysql_user }}
  password={{ wp_mysql_password }}
  priv=*.*:ALL
  become: yes

5. WordPress

To get the WordPress tar file from the official site, extract it and modify the wp-config.php with appropriate data we will add the following contents into wordpress-playbook/roles/wordpress/tasks/main.yml

- name: Download WordPress
  get_url:
  url=https://wordpress.org/latest.tar.gz
  dest=/tmp/wordpress.tar.gz
  validate_certs=no

- name: Extract WordPress
  unarchive: src=/tmp/wordpress.tar.gz dest=/var/www/   copy=no
  become: yes

- name: Update default Apache site
  become: yes
  lineinfile:
  dest=/etc/apache2/sites-enabled/000-default.conf
  regexp="(.)+DocumentRoot /var/www/html"
  line="DocumentRoot /var/www/wordpress"
  notify:
    - restart apache

- name: Copy sample config file
  command: mv /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php creates=/var/www/wordpress/wp-config.php
  become: yes

- name: Update WordPress config file
  lineinfile:
  dest=/var/www/wordpress/wp-config.php
  regexp="{{ item.regexp }}"
  line="{{ item.line }}"
  with_items:
    - {'regexp': "define\\('DB_NAME', '(.)+'\\);", 'line': "define('DB_NAME', '{{wp_mysql_db}}');"}
    - {'regexp': "define\\('DB_USER', '(.)+'\\);", 'line': "define('DB_USER', '{{wp_mysql_user}}');"}
    - {'regexp': "define\\('DB_PASSWORD', '(.)+'\\);", 'line': "define('DB_PASSWORD', '{{wp_mysql_password}}');"}
  become: yes

Finally, we will add the following snippet to ansible-demo/roles/wordpress/handlers/main.yml

# handlers file for wordpress
- name: restart apache
  service: name=apache2 state=restarted
  become: yes

3. Running Ansible

We can use the following command:

$ ansible-playbook playbook.yml -i hosts -u username -K