Automating WordPress deployment to Elastic Beanstalk

Updated Jan 25, 2018

This post is part of the series WordPress and Elastic Beanstalk.

Introduction

In the previous post Getting Started we created a new WordPress application deployed to an Elastic Beanstalk environment.

We manually cobbled together a source directory containing WordPress and Elastic Beanstalk configuration files, zipped up the directory into an artifact.zip package, and uploaded the bundle to Elastic Beanstalk using the web interface.

This process is fine for a one-off job but if you’re developing plugins or themes for your website, or upgrading WordPress or installing plugins it’s a good idea to automate the build and deployment processes. In this post we’ll create a project that will allow us to update our Elastic Beanstalk environment with a single command line. We’ll create scripts to copy files from our local WordPress installation, add in Elastic Beanstalk configuration files and other server files, and deploy the result to Elastic Beanstalk.

The files referenced below are available as a git repository. You can download or clone the repository and follow the README to get started. The below explains the files in more detail.

This post assumes that you have a local WordPress installation, an Elastic Beanstalk environment similar to the one described in an earlier post, access to a Bash shell (eg, Terminal on a Mac), and have installed the Elastic Beanstalk CLI.

Table of contents

Create the project

Download or clone the git repository to your local machine. The resulting directory should appear as follows:

assets
.ebextensions
env.config
server-files
.htaccess
wp-config.php
.gitignore
build.sh
deploy.sh
README.md

.ebextensions

This directory holds configuration files for Elastic Beanstalk. During the build the entire directory is copied to the root of our source bundle. This directory has a single file env.config but you can add other configuration files and they will be included in the deployment.

env.config

This defines environment variables that are referenced by the wp-config.php file we’ll review later:

env.config Download Copy
option_settings:
  aws:elasticbeanstalk:application:environment:
    AWS_ACCESS_KEY_ID: 'Access key id for S3'
    AWS_SECRET_ACCESS_KEY: 'Secret access key for S3'
    WP_AUTH_KEY: 'key'
    WP_SECURE_AUTH_KEY: 'key'
    WP_LOGGED_IN_KEY: 'key'
    WP_NONCE_KEY: 'key'
    WP_AUTH_SALT: 'salt'
    WP_SECURE_AUTH_SALT: 'salt'
    WP_LOGGED_IN_SALT: 'salt'
    WP_NONCE_SALT: 'salt'
    RDS_DB_NAME: 'RDS database name'
    RDS_HOSTNAME: 'RDS database endpoint'
    RDS_PORT: 'RDS database port'
    RDS_USERNAME: 'RDS database username'
    RDS_PASSWORD: 'RDS database password'

Replace all the placeholder text (in red) with your own values. If you’re unsure where to find these refer to the earlier post.

Note that your modified env.config file will contain sensitive information and should not be committed to git or any other repository.

server-files

This directory includes files that we want at the root level of our source bundle. The build script will include all files in this directory.

.htaccess

WordPress generates a .htaccess file to route to your WordPress directory and to enable pretty permalinks. Since you may have a different .htaccess file in your local environment, we use this one when deploying to Elastic Beanstalk.

.htaccess Copy
# BEGIN WordPress
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.php [L]
</IfModule>
# END WordPress

This is a default .htaccess file that should work in most cases. Modify it as needed to suit your environment.

wp-config.php

This is our WordPress configuration file. Although you probably have a wp-config.php file in your local WordPress installation, it’s likely not suitable for your Elastic Beanstalk environment. Maintaining separate configuration files means we can develop locally and deploy to production without having to swap configuration files in and out.

wp-config.php Download Copy
<?php
// AWS configuration for WP Offload S3.
define('DBI_AWS_ACCESS_KEY_ID', $_SERVER['AWS_ACCESS_KEY_ID']);
define('DBI_AWS_SECRET_ACCESS_KEY', $_SERVER['AWS_SECRET_ACCESS_KEY']);
// MySQL configuration.
define('DB_NAME', $_SERVER['RDS_DB_NAME']);
define('DB_USER', $_SERVER['RDS_USERNAME']);
define('DB_PASSWORD', $_SERVER['RDS_PASSWORD']);
define('DB_HOST', $_SERVER['RDS_HOSTNAME'] . ':' . $_SERVER['RDS_PORT']);
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
// Authentication keys and salts.
define('AUTH_KEY', $_SERVER['WP_AUTH_KEY']);
define('SECURE_AUTH_KEY', $_SERVER['WP_SECURE_AUTH_KEY']);
define('LOGGED_IN_KEY', $_SERVER['WP_LOGGED_IN_KEY']);
define('NONCE_KEY', $_SERVER['WP_NONCE_KEY']);
define('AUTH_SALT', $_SERVER['WP_AUTH_SALT']);
define('SECURE_AUTH_SALT', $_SERVER['WP_SECURE_AUTH_SALT']);
define('LOGGED_IN_SALT', $_SERVER['WP_LOGGED_IN_SALT']);
define('NONCE_SALT', $_SERVER['WP_NONCE_SALT']);
// Other WordPress defaults.
$table_prefix = 'wp_';
define('WP_DEBUG', false);
if (!defined('ABSPATH'))
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');

The keys in all the $_SERVER references map to the environment variables we defined in env.config.

build.sh

This script assembles our source files and creates a zipped bundle. You need to first make it executable:

chmod +x build.sh

Enter the above in the command line. You should then be able to run the script by typing ./build.sh in the command line, though it won’t work until we make some changes.

build.sh Copy
#!/bin/bash
# Set this to your local WordPress installation.
wordpress_local=/path/to/wordpress/directory
# Exit on error.
set -e
# Create build directory.
echo Creating build directory...
rm -rf build
mkdir -p build
# Copy local WordPress installation.
echo Copying WordPress...
cp -r $wordpress_local/* build
# If you need to clean up plugins or themes you can do so here. For instance, # the theme essycode includes a scripts directory used for its own build process # that does not need to make it to production: # # rm -rf build/wp-content/themes/essycode/scripts
# Copy visible and hidden server files.
echo Copying server files...
for filename in assets/server-files/*; do
  file=$(basename $filename)
  cp $filename build/$file
done
for filename in assets/server-files/.*; do
  if [ -f $filename ]; then
    file=$(basename $filename)
    cp $filename build/$file
  fi
done
# Copy elastic beanstalk extensions.
echo Copying .ebextensions...
cp -r assets/.ebextensions build
# Create artifact.
echo Creating artifact...
rm -f artifact.zip
cd build
zip -rq ../artifact.zip .

Once you’ve changed “wordpress_local” to point to your WordPress installation you should be able to run ./build.sh to create the artifact. At this point you could upload the artifact to Elastic Beanstalk using the web interface, but we’ll add another script below to handle this automatically.

deploy.sh

This is a simple script to deploy your artifact.zip to Elastic Beanstalk. Before executing the script we need to initialize our project directory for Elastic Beanstalk. (If you haven’t installed the Elastic Beanstalk CLI do so now.)

Navigate to the project directory in your shell and type eb init. Follow the prompts, making sure to select your WordPress application at “Select an application to use”. The command will create a new directory .elasticbeanstalk with a file config.yml. We need to modify the file to tell Elastic Beanstalk what to use as our source bundle:

.elasticbeanstalk/config.yml
branch-defaults:
  master:
    environment: <your-environment-name>
deploy:
  artifact: artifact.zip
global:
  application_name: <your-application-name>
  default_ec2_keyname: <your-ec2-keyname>
  default_platform: <your-platform>
  default_region: <your-region>
  profile: <your-profile-name>
  sc: <your-source-control>

The deploy script is straightforward:

deploy.sh Copy
#!/bin/bash
./build.sh
eb deploy

Ensure that the deploy script is executable by typing chmod +x deploy.sh in your shell. You should now be able to enter ./deploy.sh in your shell to build and deploy your application to Elastic Beanstalk.

Next steps

Now that you hopefully have a build process in place you can focus on developing your application. Check out Set Cache Controls in Elastic Beanstalk and Enable Server-side Compression in Elastic Beanstalk to improve your site’s performance, and Add a Custom Domain to an Elastic Beanstalk WordPress application to use your own domain name. Please feel free to ask questions or suggest improvements in the comments section below.

Comments Leave a comment

  • Yury Barony
    Excellent, post, it helped me a lot!

Leave a comment