Autoscaling for LAMP on AWS |Creating a LAMP Stack AMI : Part 1

By Flux7 Labs
January 13, 2014

This is part 1 of the AWS Autoscaling Tutorial for LAMP in AWS series. This autoscaling step-by-step guide would walk you through:

Part 1: Creating a LAMP Stack AMI

Part 2: Setting up Autoscaling Groups.

Part 3: Load Test the environment

Part 4: Choose instance type

First, let’s discuss how to prepare the Amazon Machine Image -AMI-  create an Elastic Load Balancer and Amazon RDS, verify the application and terminate the instance.

Prepare AMI

In AWS Autoscaling, create an AMI with all required packages installed. This AMI will be used as a template to launch instances in autoscaling. For AWS LAMP Stack, you should install and fine tune the latest versions of Apache and PHP.

1. Log in to AWS console.

2. Navigate to EC2 services. Make sure to switch to the desired region before launching instances.

3. Click on “Launch instance”.

4. Select your favorite Linux AMI in Classic Wizard.

For this article we used CentOS 6.3 from the community AMIs, but OpenSuse and Ubuntu are also good choices.

5. Launch a micro instance from the selected AMI with the desired AWS Security Group  and Key pair. Remember, this instance is only for creating an AMI and will be terminated once LAMP Stack is installed on it.

6. Now log in to the instance and perform the PHP and Apache installation steps. For this article, we used Cygwin to connect the Linux servers. Make sure you open port 22 to allow SSH access using security groups.

We modified the “default” security group to open the SSH port. We recommend that you not completely open port 22 for SSH, but rather allow incoming requests to SSH from your specific IP address. In our case the IP address was

$ ssh –I LAMP_AMI.pem <a href=""></a>
<a href=""></a>
$ yum install httpd.x86_64 httpd-devel.x86_64 mod_ssl.x86_64 php.x86_64 php-common.x86_64 php-devel.x86_64 php-gd.x86_64 php-mbstring.x86_64 php-mysql.x86_64 php-pdo.x86_64 php-soap.x86_64 php-xml.x86_64 php-xmlrpc.x86_64 php-pecl-apc-devel.x86_64 php-pecl-memcache.x86_64 -y

Once you’ve successfully executed these commands, Apache and PHP will install. Note that the commands we’ve used are specific to CentOS 6.3. Choosing a different OS or a different CentOS may cause these commands to fail to execute. The php modules listed above are required for WordPress setup and they may vary depending upon your requirements.

Now update the PHP and Apache configurations for your Instance types and for the expected load on application. We used t1.Micro for this article. Keep in mind that a production system’s instance types need to be chosen very carefully, and that the software must be tuned to those particular types.

Read more on selecting instance types in Part 4 of this series.

Install Postfix to send email notification for the script used in the next step.

$ yum install postfix
$ chkconfig –level 2345 postfix on
$ chkconfig –level 2345 httpd off

7. Now all of the required packages are installed and fine-tuned.

So, how does one deploy the code into AMI?

The method described here automates the deployment. One cron job will be included in AMI, and it will download and deploy the latest available S3 code. That means that code updates will deploy to S3 every time, but not to instances. Every time a new instance is up, the instance will automatically download updates from the S3 bucket and deploy them.

What follows is a script scheduled for machine boot-up. It requires updating based on specific user configurations and file paths.

S3_URL= “<a href=""></a>” #Change the following paths as per your requirement.
APACHE_RESTART=`/etc/init.d/httpd restart`
#Get the instance ID from AWS metadata.
###download the latest code from s3 and deploy###
cd /tmp
wget $S3_URL
if [ $? –ne 0 ]
pkill -9 httpd
mail –s “Code Download Failed from S3##$INSTANCE_ID”  <a href=""></a> #Provide valid email ID here”
exit 1
rm –rf  &lt;/var/www/html/*&gt;
cp –r wordpress/* $DOCUMENT_ROOT
chmod 775 –R $DOCUMENT_ROOT
chown –R apache.root $DOCUMENT_ROOT
if [ $? –ne 0 ]
pkill -9 httpd
mail –s “Apache startup Failed- $INSTANCE_ID”  <a href=""></a> #Provide valid email ID here”
exit 1
##script ends here####

Put this bash script into a file in /opt/ directory:

$vim /opt/
$chmod +x /opt/

Open the Crontab and add this script to start at machine boot up:

$ crontab –e

Add the following script:

Save your changes and deploy the code by running the script to test whether or not the application is working as expected. This step is mandatory before creating an AMI. If you find any issues with the code or PHP/Apache settings, be sure to fix them before creating an AMI.

Bundle and Upload the Code to S3

  1. Update the code with Amazon RDS DB configuration parameters.

  2. Now zip the working copy of the code and upload it to the S3 location. The S3 location should match the location in the script, and also match the zip file name.

  3. Upload the zip file to the S3 bucket that matches the script. You can upload the zip file by using the console or any third party tool like Cloudberry.

  4. Grant read permissions to download the code from S3 to app servers.

Create the ELB

Go to Services-> EC2 -> Load Balancers and select “Create Load Balancer”.


Keep Healthy/Unhealthy threshold limits to 4 because that’s proven to be an ideal value. Also make sure index.html is available in the Document root. Amazon Elastic Load Balancer looks for the index.html as a health check and removes the instance from the load balancer if it doesn’t get the 200 response. Create the required security groups and key pair for the autoscaling instances.

Create RDS

1. Go to Services -> RDS and select the MySQL engine.

2. Select instance types, provide the details for all required fields and launch the instance. The RDS configuration details chosen for this article can be seen below.

How should you select the DB instance type? There are many monitoring tools available for monitoring MySQL performance. If AWS RDS is used for MySQL, then it’s important to consider AWS CloudWatch metrics. Since it’s not possible to install agents in RDS, you can rely upon CloudWatch metrics.

By default, CloudWatch contains all required RDS monitoring metrics. Be sure to monitor the memory, CPU, DB connections and network I/O before you scale up the server.

Ideally, m1.small RDS can handle up to 75 concurrent connections easily. but that depends upon the DB queries and the code.

3. After launching RDS, open the 3306 port to the app servers group.

4. Import the DB and try connecting to the application. Then use standard MySQL commands to import the dump.

Example: mysql –h rds-endpoint –u user –ppasswwd databasename < dump.sql

Verify the Application

At this point, it’s mandatory that you thoroughly verify the application. Make sure to check Login/logout, upload/download and any other relevant verifications. Create an AMI only after making sure that the application is working as expected. Fix any issues before proceeding to the next step.

EC2 Create AMI

1. Delete the command history:

$ history -c

Delete the deployed code and logs files and make things as clean as possible.

2. Create an AMI using the micro instance that you’ve configured.

Go to AWS Console->Services->EC2, right click on the instance, and select “Create Image” (EBS AMI).

Name the AMI using a date as the naming convention. Do not select “No reboot”. Instead, allow it to reboot while creating the AMI. The reboot will give you a consistent snapshot of EBS.

In a few minutes an AMI will be created and made available.

Keep the root partition as minimal as possible because that helps to prevent bugs. You don’t need large space for root partition in autoscale because these instances keep rotating.

Terminate the Instance

Finally, terminate the instance by right clicking on the instance and selecting “Terminate”. Keep the ELB and RDS running.

Watch out for Part 2, same time tomorrow, on how to setup autoscaling groups!

Update: Check part 2 on how to setup AWS autoscaling groups here.