Salt States by Example | Part 6 | Install Wordpress using Salt

By: rahul On: Tue 21 November 2017
In: Devops
Tags: #devops #configuration-management #linux #saltstack

Greetings Wanderer!

This is a continuation on our attempt to write a complete Salt State. Before proceeding, if you haven't already, please check the links/articles listed below:

> Saltstack By Example | Part 1 | Installation
> Saltstack By Example | Part 2 | Configuration
> Saltstack By Example | Part 3 | Basic Commands
> Saltstack By Example | Part 4 | Salt State Examples

> Salt States by Example | Part 1 | Install a Salt Minion on CentOS or Debian
> Salt States by Example | Part 2 | Install Nginx using Saltstack
> Salt States by Example | Part 3 | Install MySQL, PHP and PHP-FPM using Saltstack
> Salt States by Example | Part 4 | Create and Configure an Nginx Virtual Host
> Salt States by Example | Part 5 | Install WP-CLI using Salt
>> Salt States by Example | Part 6 | Install Wordpress using Salt (<== We are here)

In the previous article, we saw how to install the command-line tool wp-cli on a Salt Minion. In this post, we'll see how to go about installing and configuring Wordpress using saltstack on the same Salt Minion.

Prerequisites
  • A Salt Master
  • A Salt Minion that runs a Debian minimal install or a CentOS minimal install - the installation is outlined in Part 1
  • This is what our directory structure looks like:
.
|-- common    <=== COMPLETED
|-- nginx     <=== COMPLETED
|   `-- repofiles
|-- mysql     <=== COMPLETED
|-- php       <=== COMPLETED
|   `-- files
|-- wordpress 
|   `-- files
|-- wpcli     <=== COMPLETED
|   `-- files
`-- wp_user   <=== COMPLETED
    `-- files
        |-- templates
        `-- wptest
            |-- logs
            `-- public_html

1. Install Wordpress

1a. As always, we'll begin by declaring a few variables, using the map.jinja file (wpcli/map.jinja):

{%  set wordpress = salt['grains.filter_by']({
    'Debian': {
        'url': 'http://wptest.com',
        'name': 'WP TEST BLOG',
    },
    'RedHat': {
        'url': 'http://wptest.com',
        'name': 'WP TEST BLOG',
    }
}) %}

1b. Next, we'll create the MySQL user and databases required by the Wordpress application. This is done using the createdb.sls file (wordpress/createdb.sls):

{% set mysql_root_pass = salt['pillar.get']('mysql:server:root_password', salt['grains.get']('server_id')) %}
{% set wp_pass = salt['pillar.get']('mysql:server:wp_password', salt['grains.get']('server_id')) %}

wpuser_user:
  mysql_user.present:
    - host: 'localhost'
    - connection_user: 'root'
    - connection_pass: '{{ mysql_root_pass }}'
    - connection_charset: utf8
    - name: 'wptest'
    - password: {{ wp_pass }}

wpuser_database:
  mysql_database.present:
    - name: wptest
    - host: 'localhost'
    - connection_user: 'root'
    - connection_pass: '{{ mysql_root_pass }}'
    - connection_charset: utf8

wpuser_grants:
  mysql_grants.present:
    - database: wptest.*
    - grant: ALL PRIVILEGES
    - user: wptest
    - host: 'localhost'
    - connection_user: 'root'
    - connection_pass: '{{ mysql_root_pass }}'
- connection_charset: utf8

NOTE: All we've done is create the MySQL user, the MySQL database and granted all privileges on the database, to the new database user - all these steps are done on the Salt Minion.

1c. Again, here I've used a 2-line shell script to install the Wordpress application. Salt then copies the script to the Minion and runs the script there (within the Virtual Host user's home directory). The shell script:

1
2
3
4
5
#!/bin/bash

cd /home/{{ username }}/public_html
wp core download --allow-root --locale=en_GB
cd

1d. And now we run salt to install Wordpress, using install.sls (wordpress/install.sls):

{% from "wordpresser/wordpress/map.jinja" import wordpress %}
{% from "wordpresser/wp_user/map.jinja" import wpuser %}

{% set mysql_root_pass = salt['pillar.get']('mysql:server:root_password', salt['grains.get']('server_id')) %}
{% set wp_pass = salt['pillar.get']('mysql:server:wp_password', salt['grains.get']('server_id')) %}
{% set wp_host = salt['pillar.get']('mysql:server:host', salt['grains.get']('server_id')) %}
{% set wp_adminuser = salt['pillar.get']('admin:wpapp:user', salt['grains.get']('server_id')) %}
{% set wp_adminpass = salt['pillar.get']('admin:wpapp:pass', salt['grains.get']('server_id')) %}
{% set wp_adminmail = salt['pillar.get']('admin:wpapp:mail', salt['grains.get']('server_id')) %}

install_wp:
  cmd.script:
    - cwd: /home/{{ wpuser.username }}/public_html
    - source: salt://wordpresser/wordpress/files/install-wp.sh
    - user: root
    - template: jinja
    - context:
      username: {{ wpuser.username }}

config_wp:
  cmd.run:
    - cwd: /home/{{ wpuser.username }}/public_html
    - name: 'wp core config --dbname=wptest --dbuser=wptest --dbpass={{ wp_pass }} --dbhost={{ wp_host }} --dbprefix=wp_ --allow-root'

core_wp:
  cmd.run:
    - cwd: /home/{{ wpuser.username }}/public_html
    - name: 'wp core install --url="{{ wordpress.url }}" --title="{{ wordpress.name }}" --admin_user="{{ wp_adminuser }}" --admin_password="{{ wp_adminpass }}" --admin_email="{{ wp_adminmail }}" --allow-root'

NOTE 1: check how the variables are called from other map.jinja files outside the current directory
NOTE 2: Once Wordpress is installed, using install_wp, we run the wp core commands, which are part of the wp-cli package, to (a) configure the database and (b) configure the Admin credentials
NOTE 3: Note how the Wordpress Admin credentials are assigned using the pillar variables. The pillar variables are assigned like so:
pillar/admin.sls

admin:
  wpapp:
    user: 'admin'
    pass: 'test123'
    mail: 'admin@wptest.com'

pillar/mysql.sls

mysql:
  server:
    root_user: 'root'
    root_password: 'testpass'
    user: mysql
    host: localhost
    wp_password: 'test123'

Here's what the completed wordpress directory structure should look like:

wordpress/
|-- createdb.sls
|-- files
|   `-- install-wp.sh
|-- install.sls
`-- map.jinja

1e. Edit the init.sls file to include the wordpress files:

include:
  - wordpresser.common.packages
  - wordpresser.nginx.repo
  - wordpresser.nginx.packages
  - wordpresser.nginx.firewalld
  - wordpresser.mysql.packages
  - wordpresser.mysql.firewalld
  - wordpresser.mysql.mysql_secure
  - wordpresser.php.packages
  - wordpresser.wp_user.create
  - wordpresser.wp_user.configure
  - wordpresser.wpcli.install
  - wordpresser.wordpress.createdb
  - wordpresser.wordpress.install

1f. Run salt command - salt '*' state.apply
If it runs successfully, a Wordpress application will be installed within the Virtual host user's home directory, on the Minions.

This concludes the process of building a complete LEMP server AND installing a complete Wordpress application, with wp-cli support, using Saltstack.

A complete version of the code is available at this GitHub repository: Wordpresser


If you found the article helpful, please share or cite the article, and spread the word:


For any feedback or corrections, please write in to: rahul [at] muchbits [dot] com