Elastic Beanstalk for Auto Scaling WordPress

Elastic Beanstalk for wordpress

This wordpress site used to run on AWS Elastic Load Balancer with Auto Scaling that I configured manually. I realized pretty soon that I’ll be facing issues when wordpress is updated or new plugins are added/updated. Since the wordpress folder will have new files, you have to make sure that new instances launched by Auto Scaling will also contain these updates as well.

You can create a new AMI with all the updates, but then you would have to create a new Launch Configuration and edit Auto Scaling to use the new Launch Configuration. You can store wordpress installation files on S3 bucket and use a user data script to pull the files when a new instance launches, but S3 synchronization doesn’t quite do mirroring (it doesn’t delete non-existing items in source from S3 buckets) and synchronizing couple of thousand files is not very cost efficient. Thankfully, Amazon Web Services provide Elastic Beanstalk service which allows you to push updates easily.

Migrate to Elastic Beanstalk infrastructure

First thing to do is zip up your current wordpress installation. On the Amazon Linux EC2 instance, execute

$ zip peacefulan.zip -r * .[^.]*

 

Upload it to S3 bucket with aws cli (installed by default on Amazon Linux AMIs)

$ aws s3 cp peacefulan.zip s3://your-bucket-name/peacefulan.zip

 

From AWS Management Console go to Elastic Beanstalk. Click on “Create Environment” and “Create web server”.

Select PHP as Preferred configuration. I chose the latest AWS Linux AMI. Select Load balancing, auto scaling as Environment Type.

env1

Choose S3 URI as the Source and enter the link of the previously uploaded file. I chose Batch size as 1 instance at a time because percentage based batch doesn’t really matter for a handful of instances.

env2

Choose an environment name and be sure to check its availability.

env3

Since this is not a new installation and there is a database in place already for wordpress, only check Create the environment inside a VPC.

env4

I selected t2.micro, which is a free tier instance, for Instance Type. Make sure to choose a key pair that you already have. Select Basic health reporting as Enhanced service will cost extra. You can leave the Root Volume settings as default or set it to your preference.

env5

In VPC Configuration, choose your VPC and make sure to check all Availability Zones for both ELB and EC2. ELB visibility has to be External for your site to be accessible from the internet.

env6

For the Permissions, make sure the Instance profile is assigned a role that has a S3 privileges.

env7

On the final screen, review your information, make any changes as necessary, and click Create.
If everything went right, you will see a large green check mark on the status screen of your environment after several minutes.

eb_end

You can verify that your wordpress site is live by clicking on the environment URL.

If you are using Route53, then change your A record to point to Elastic Beanstalk environment URL at this point.

Make deployments easier

The Elastic Beanstalk setup is complete. However, zipping up the wordpress folder, downloading it and then uploading to the Elastic Beanstalk for deployment is still time consuming. We can automate the process with a small script.

Create a file in the root directory of your wordpress installation (“deploy.sh” for example) with this code.

#!/bin/bash
timestamp=$(date +%s)
filename=peacefulan-$timestamp
version=$(date +'%m.%d.%y %T')
zip $filename.zip -r * .[^.]*
aws s3 cp $filename.zip s3://elasticbeanstalk-us-west-1-xxxxxxxxxxxx/$filename.zip
aws --region us-west-1 elasticbeanstalk create-application-version --application-name applicationname --version-label "$version" --source-bundle S3Bucket=elasticbeanstalk-us-west-1-xxxxxxxxxxxx,S3Key=$filename.zip
aws --region us-west-1 elasticbeanstalk update-environment --environment-name environmentname --version-label "$version"
rm $filename.zip

 

Make sure you edit the script to match your environment. Change the region to match your configuration and use your own Elastic Beanstalk S3 bucket name. Note that you have to provide your application name when creating application version and environment name when updating environment.

Execute with the following command.

$ sudo sh deploy.sh

 

The script will create a zip file with a unique filename, upload it to the Elastic Beanstalk’s S3 bucket, create an application version with the timestamp as the version label, and then deploy it.

Watch your environment’s dashboard. The history will be updated real time with deployment information. Now anytime you want to deploy a new version, simply execute this script.

You can rollback to previous versions or delete previous versions in Application Versions section of the Elastic Beanstalk.

Update: To figure out on which EC2 instance you just updated your wordpress site, use the Instance Metadata.

6 thoughts on “Elastic Beanstalk for Auto Scaling WordPress

  1. bucketlist

    i dont know a lot about buckets and stuff. where do i put my access key id or secret passphrase? i get the error:

    upload failed: ./test.txt to s3://elasticbeanstalk-us-west-2-BUCKETNAME/test.txt An error occurred (NoSuchBucket) when calling the PutObject operation: The specified bucket does not exist

    and what should BUCKETNAME be really? the name of my bucket only? not the url? I think the above is either a permissions problem (i dont recall setting permissions on the bucket to have elastic beanstalk talk to it) or a path problem as evidenced by the error. I am finding it hard to figure out what my bucket name is. Any help appreciated.

    Reply
    1. bluedha Post author

      You can enter your access key and secret passphrase with “aws configure” command. It will also set your region and output format (best to leave it at default).

      If you have set up elastic beanstalk, the bucket would have been created for you with a name like “elasticbeanstalk-us-west-2-” followed by string of numbers.
      Whenever you deploy code for your elastic beanstalk, this bucket is where the file is uploaded to.
      If this bucket does not exist, then your elastic beanstalk might not be complete. Try creating a bucket through management console and uploading a file to it with the aws cli.

      Reply
  2. grendug kruden

    Can you please update with how to make this deployment work on multiple instances?
    Where will assets be located when uploaded from the application?

    Will highly appreciate it.
    Thanks!

    Reply
    1. bluedha Post author

      When you say multiple instances, do you mean under the same elastic beanstalk application or individual instances that are not tied together?
      If you mean the former, then executing the script will upload the application to s3 storage and elastic beanstalk will automatically deploy it to all instances under that application name.
      If you mean the latter, then I’d expect you would need to modify the script to upload and extract to each instance. However, I don’t see an easy way of doing this using the bash script (ftp maybe?).
      I’m sure it’s doable, but one of the reasons why elastic beanstalk is used is for this exact purpose; deploying same application to multiple instances.

      Reply
  3. awsquest

    I was wondering how to migrate the DB. As I currently have the site hosted on EC2, I want to move it to elastic beanstalk for scalability and availability. I know how to zip up the wordpress site and move it, but the database wont come with it, or will it if I zip up the whole server?

    Reply
    1. bluedha Post author

      It depends on where your DB is hosted. If it is hosted on AWS RDS, then you don’t have to do anything because the underlying wordpress configuration does not change. If it is hosted on the same EC2 instance as wordpress, then you might want to migrate to RDS. Migration can be done with AWS DMS (Database Migration Service) or manually by backing up your wordpress database and restoring it on a new DB server by:
      mysqldump --user username --password databasename > filename.sql
      mysql --user username --password databasename --host rds-endpoint < filename.sql
      Make sure that the new RDS instance can communicate with the EC2 instances by opening the right ports in the security group setting.
      If you are interested in AWS DMS, take a look at AWS Database Migration Service Pointers.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.