Deploying a High-Availability WordPress Website with Amazon EFS and AWS Elastic Beanstalk

May 18, 2023
/
Mallikharjuna Kambampati
/
No items found.

As a popular CMS platform, WordPress sits at the core of thousands—if not millions—of websites. It can be deployed not only as an end-to-end CMS platform but in other forms as well. The growing trend is to use headless WordPress with frameworks like React and Next.js, allowing the platform to be more flexible.

Said flexibility of WordPress makes it suitable for high-availability deployment. Thanks to services like AWS, you don’t need to set up a complex array of cloud instances—or even maintain your own cluster—to have a WordPress-based site that scales fluidly. Deploying a high-availability WordPress website is something you can now do with external storage through Amazon EFS and the automation process through AWS Elastic Beanstalk.

How Robust Can It Be?

Before we get to the steps to take in order to create a WordPress site with high availability, it is interesting to take a closer look at how the platform needs to be set up. AWS Elastic Beanstalk is the perfect environment to use due to the fact that it is highly available out of the box.

Rather than relying on a single cloud instance, Elastic Beanstalk automatically configures servers in different AWS Availability Zones and sets up Elastic Load Balancing for load management. The website is designed then to use Amazon Elastic File System (Amazon EFS) as shared storage for uploaded files, plugins, and themes.

The basic storage setup is more than capable of handling heavy loads, but you can take the config a step further by integrating Amazon CloudFront distribution. You can also utilize Memcache by integrating plugins like W3 Total Cache with Amazon ElastiCache.

A High-Availability WordPress Website

This process configures Elastic Beanstalk for high availability. From the Elastic Beanstalk console, configure the Auto Scaling Group of your EB. You want to set the minimum number of instances to two for maximum performance.

The rest is easy from here. You can upgrade WordPress, optimize your file storage, and begin customizing your new WordPress site directly from WP-Admin. Elastic Beanstalk will provide the necessary resources for your new site to function optimally. As below, we have updated the extensions in our project to centralize the uploads, themes, plugins content using Amazon EFS. Create a folder called .ebextensions in your project root and put the following file into it, called “efs.config’.

How to Deploy a High-Availability WordPress Website with Amazon EFS and AWS Elastic Beanstalk

option_settings:
 aws:elasticbeanstalk:application:environment:
   MOUNT_DIRECTORY: '/mnt/efs'
   REGION: '`{"Ref": "AWS::Region"}`'

packages:
 yum:
   nfs-utils: []
   jq: []

files:
 "/tmp/mount-efs.sh" :
     mode: "000755"
     content : |
       #!/bin/bash
  EFS_REGION=$(/opt/elasticbeanstalk/bin/get-config environment | jq -r '.REGION')
     EFS_MOUNT_DIR=$(/opt/elasticbeanstalk/bin/get-config environment | jq -r '.MOUNT_DIRECTORY')
      EFS_FILE_SYSTEM_ID=$(/opt/elasticbeanstalk/bin/get-config environment | jq -r '.FILE_SYSTEM_ID')

       echo "Mounting EFS filesystem ${EFS_DNS_NAME} to directory ${EFS_MOUNT_DIR} ..."

       echo 'Stopping NFS ID Mapper...'
       service rpcidmapd status &> /dev/null
       if [ $? -ne 0 ] ; then
           echo 'rpc.idmapd is already stopped!'
       else
           service rpcidmapd stop
           if [ $? -ne 0 ] ; then
               echo 'ERROR: Failed to stop NFS ID Mapper!'
               exit 1
           fi
       fi

       echo 'Checking if EFS mount directory exists...'
       if [ ! -d ${EFS_MOUNT_DIR} ]; then
           echo "Creating directory ${EFS_MOUNT_DIR} ..."
           mkdir -p ${EFS_MOUNT_DIR}
           if [ $? -ne 0 ]; then
               echo 'ERROR: Directory creation failed!'
               exit 1
           fi
       else
           echo "Directory ${EFS_MOUNT_DIR} already exists!"
       fi

       mountpoint -q ${EFS_MOUNT_DIR}
       if [ $? -ne 0 ]; then
           echo "mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ${EFS_FILE_SYSTEM_ID}.efs.${EFS_REGION}.amazonaws.com:/ ${EFS_MOUNT_DIR}"
           mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ${EFS_FILE_SYSTEM_ID}.efs.${EFS_REGION}.amazonaws.com:/ ${EFS_MOUNT_DIR}
           if [ $? -ne 0 ] ; then
               echo 'ERROR: Mount command failed!'
               exit 1
           fi
           chmod 777 ${EFS_MOUNT_DIR}
           runuser -l  ec2-user -c "touch ${EFS_MOUNT_DIR}/it_works"
           if [[ $? -ne 0 ]]; then
               echo 'ERROR: Permission Error!'
               exit 1
           else
               runuser -l  ec2-user -c "rm -f ${EFS_MOUNT_DIR}/it_works"
           fi
       else
           echo "Directory ${EFS_MOUNT_DIR} is already a valid mountpoint!"
       fi

       echo 'EFS mount complete.'

       echo "creating folders (uploads, themes, plugins)"
       mkdir -p /mnt/efs/uploads
       chown webapp:webapp /mnt/efs/uploads
       mkdir -p /mnt/efs/plugins
       chown webapp:webapp /mnt/efs/plugins
       mkdir -p /mnt/efs/themes
       chown webapp:webapp /mnt/efs/themes




commands:
 01_mount:
   command: "/tmp/mount-efs.sh"
container_commands:
 01-rm-wp-content-uploads:
   command: rm -rf /var/app/ondeck/wp-content/uploads
 02-rm-wp-content-plugins:    
   command: rm -rf /var/app/ondeck/wp-content/plugins
 03-rm-wp-content-themes:
   command: rm -rf /var/app/ondeck/wp-content/themes
 04-symlink-uploads:
   command: ln -snf /mnt/efs/uploads /var/app/ondeck/wp-content/uploads
 05-symlink-plugins:    
   command: ln -snf /mnt/efs/plugins /var/app/ondeck/wp-content/plugins
 06-symlink-themes:    
   command: ln -snf /mnt/efs/themes /var/app/ondeck/wp-content/themes

This code causes Elastic Beanstalk to mount the EFS volume on /mnt/efs, remove the wp-content/uploads, themes, plugins folder (if it exists) and symlink it to /mnt/efs/uploads, /mnt/efs/plugins, /mnt/efs/themes respectively so it persists and is shared between instances. This step-by-step process will help you configure a website that takes full advantage of Elastic Beanstalk’s automation, Wordpress’ flexibility, and Amazon Elastic File System’s scalability and simplicity. 

Ibexlabs is an experienced DevOps & Managed Services provider and an AWS consulting partner. Our AWS Certified DevOps consultancy team evaluates your infrastructure and make recommendations based on your individual business or personal requirements. Contact us today and set up a free consultation to discuss a custom-built solution tailored just for you.

Mallikharjuna Kambampati

Mallikharjuna is a Team Lead and DevOps Engineer at Ibexlabs, with experience in managing AWS services, and deploying DevOps tools like Jenkins, Ansible, Docker, AWS Fargate, and EKS.

Talk to an Ibexlabs Cloud Advisor