<p>Here's a rough approach to scaling any stateless app on AWS:</p>

<ol>
<li><p>Run the app in an <a href="http://docs.aws.amazon.com/autoscaling/latest/userguide/AutoScalingGroup.html" rel="nofollow noreferrer">Auto Scaling Group (ASG)</a>. An ASG makes it easy to manage multiple servers, will automatically replace failed servers, and allows you to automatically scale the number of servers up or down in response to load.</p></li>
<li><p>To run an ASG, you need to create a <a href="http://docs.aws.amazon.com/autoscaling/latest/userguide/LaunchConfiguration.html" rel="nofollow noreferrer">Launch Configuration</a>. This is a "template" that specifies the configuration for each server in the ASG: i.e., what type of instance to run (e.g. <code>t2.micro</code>), what AMI to run on the instance, the security group settings, etc.</p></li>
<li><p>The <a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html" rel="nofollow noreferrer">AMI</a> you run on each instance in the ASG should have your app already installed (i.e., your PHP app). You can define your AMI as code using a tool like <a href="https://www.packer.io/" rel="nofollow noreferrer">Packer</a>. </p></li>
<li><p>The app in your AMI should be configured to run on boot using a process supervisor (e.g., using <a href="https://www.freedesktop.org/wiki/Software/systemd/" rel="nofollow noreferrer">systemd</a> or <a href="http://supervisord.org/" rel="nofollow noreferrer">supervisord</a>; this will also ensure the app is restarted automatically if it crashes. </p></li>
<li><p>Every time you change something in your app, run a build process to create a new AMI, update the Launch Configuration to use this new AMI, and roll that AMI out across your ASG. For example, you could do a zero-downtime deployment (somewhat similar to a <a href="https://martinfowler.com/bliki/BlueGreenDeployment.html" rel="nofollow noreferrer">blue-green deployment</a>) by doubling the size of the ASG, waiting until all the new servers (from the updated Launch Configuration) launch and pass health checks, and then reducing the ASG back to its previous size (the ASG will terminate oldest instances by default). </p></li>
<li><p>With an ASG, you have more than one server, but you want to give your users a single endpoint to use. The typical solution to this is to deploy a load balancer in front of the ASG. If you're building a typical HTTP/HTTPs app (e.g., just about all PHP apps), you'll want to use the <a href="http://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html" rel="nofollow noreferrer">Application Load Balancer (ALB)</a>; if you're building an app that listens directly for TCP connections, you'll want the <a href="http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/introduction.html" rel="nofollow noreferrer">Load Balancer Classic</a> or <a href="http://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html" rel="nofollow noreferrer">Network Load Balancer</a>. Whichever load balancer you pick, AWS will create a domain name for it that you can use, and any requests you send to that domain name will be routed in round-robin fashion to different servers in your ASG. </p></li>
<li><p>You should a) configure the load balancer to perform health checks on your app so that it only routes to healthy servers and b) configure your ASG to register all of its servers in the load balancer automatically and to use the load balancer for health checks.</p></li>
<li><p>You can create <a href="http://docs.aws.amazon.com/autoscaling/latest/userguide/WhatIsAutoScaling.html" rel="nofollow noreferrer">Auto Scaling Policies</a> for the ALB that change the number of servers in your ASG depending on various CloudWatch metrics. For example, you could configure the ASG to add servers when average CPU usage is over 80% and to remove servers when CPU usage drops below 60%.</p></li>
</ol>

<p>For more info, check out <a href="https://www.airpair.com/aws/posts/building-a-scalable-web-app-on-amazon-web-services-p1" rel="nofollow noreferrer">A Comprehensive Guide to Building a Scalable Web App on Amazon Web Services</a>.</p>

CC BY-SA 3.0
2017-09-26T13:32:17.570Z
Are you sure about this?: "The AMI you run on each instance in the ASG should have your app already installed ". My Manager strongly believes that the application code should not be part of the AMI. Do you have a reference for this?
Mick
CC BY-SA 3.0
2017-09-27T03:30:16.803Z
@Mick Heh, yea, pretty sure :) The approach I'm describing is called "Immutable Infrastructure".  If you google it, you'll find plenty books and blog posts on the topic (I also talk about it in my own book, *[Terraform: Up & Running](https://www.terraformupandrunning.com/)*). The idea is to create immutable, versioned images that have all of your application code baked in. You can then promote the exact same image from environment to environment and easily roll back if there is any issue. There are many ways to do it, such as using Packer to build AMIs or Docker to build Docker images.
Yevgeniy Brikman
CC BY-SA 3.0
2017-09-27T07:44:44.920Z
Thanks (apologies for doubting you), I have done a bit more reading since I posted and now understand Immutable and Mutable. I'm just not sure what is best for us, we tend to do small changes and often and I'm not sure I want to build a new AMI everytime we update the code.
Mick
CC BY-SA 3.0
2017-09-27T07:55:43.257Z
https://aws.amazon.com/answers/configuration-management/aws-ami-design/
Mick
CC BY-SA 3.0
2017-09-28T02:54:19.077Z
@Mick If you define your AMI using a tool like [Packer](https://www.packer.io/), then building a new AMI will be completely automated, so it's completely reasonable to build a new one after every commit. You could even extract all the dependencies that don't change often into a "base" AMI and use that as the "source" for your app AMI so the build is effectively just copying in your new code. Alternatively, look into Docker, which, due to caching, can allow you to build new images in seconds.
Yevgeniy Brikman
CC BY-SA 3.0
2017-09-24T03:16:40.590Z
2017-09-24T17:03:11.287Z
2017-09-24T17:03:11.287Z
Yevgeniy Brikman
<blockquote>
  <p>Currently all of our PHP (Laravel) applications are running on one EC2 instance. To deploy code, we SSH onto the live box and pull from CodeCommit.</p>
</blockquote>

<p>The first thing you need to decide on is a Continuous Deploy strategy. There's a lot of servers out there with different use cases, you don't have to pick the most popular, just pick the one that fits your use case.</p>

<blockquote>
  <p>I guess we want to end up with a load balancer and application servers which are created on demand.</p>
</blockquote>

<p>AWS has some great reference architectures but overall I would say start simple. At a base level you'll be using Route 53, Certificate Manager, ALB (ELBv2), VPC, and EC2. I would get used to the options you have with each of these and play with them. AWS CSA will not teach you about reference architecture, rather it will go over what each product is used for.</p>

<p>Before you go building anything for production I would also recommend using an infrastructure deployment tool. AWS provides CloudFormation out of the box but that can be difficult to interface with. Some others are Sceptre and Terraform. These allow you to store your infrastructure as code in a repository and deploy updates via a CD server.</p>

<p>Also keep in mind if you don't have Continuous Integration then you'll need to work on that, followed by Continuous Delivery, then by Continuous Deployment. Each of these is a critical step in the right direction.</p>

<p><strong>Note on "Created on Demand"</strong></p>

<p>Please keep in mind that many people come to the cloud thinking that "scaling" is instantaneous. It's not. Depending on your provisioning it can take some time. You will not scale yourself out of burst traffic. Your traffic will need to be profiled, you will need to determine your instance capacity (for web servers I measure instances in requests per second with a load testing tool), and plan accordingly.</p>

<p>Scaling is primarily designed for a gradual rise in traffic over time, such as if your website traffic grows gradually larger around noon (peak) and then settles late in the day.</p>

CC BY-SA 3.0
2017-09-23T02:18:22.053Z
2017-09-23T02:36:55.837Z
2017-09-23T02:36:55.837Z
Matt O.
<p>Currently all of our PHP (Laravel) applications are running on one EC2 instance. To deploy code, we SSH onto the live box and pull from CodeCommit.</p>

<p>We now need to scale and deploy properly.
I'm not sure where to start.</p>

<p>Most examples seem to use Elastic Beanstalk but I have been advised that this could be too restrictive.</p>

<p>I guess we want to end up with a load balancer and application servers which are created on demand. </p>

<p>Can anyone point me in the right direction? (I am a bit overwhelmed by all the AWS documentation.)</p>

<p><strong>Ok, this is the plan:</strong></p>

<p>I have signed up for A Cloud Guru and I'm going to work through some of the videos on there.</p>

<p>I'm going to sign up for a AWS Free Tier account and start tinkering.</p>

<p>I'm considering the <em>AWS Certified Solutions Architect - Associate</em>  course, this looks like a great way to develop myself.</p>

CC BY-SA 3.0
2017-09-21T10:46:04.510Z
http://docs.aws.amazon.com/autoscaling/latest/userguide/WhatIsAutoScaling.html
030
CC BY-SA 3.0
2017-09-21T13:42:52.527Z
That depends on how much you need to scale. If you are going from a single server to a thousand, it is not the same as if you are just going from a single server to two or three.
If you are staying small, I would check AutoScaling, SSM (RunCommand) and / or OpsWorks
AlvaroGMJ
CC BY-SA 3.0
2017-09-21T14:40:30.830Z
Probably 500 users max, at the moment any scaling would be better than having all the applications running on one instance. 3 servers and a load balancer would be a good start.
Mick
CC BY-SA 4.0
2020-07-09T14:17:29.660Z
@Mick - What did you end up doing?
Adrian Lynch
CC BY-SA 4.0
2020-07-09T14:35:05.480Z
If I had to do this now, I would probably look at the Azure App Service or similar.
Mick
<amazon-web-services><autoscaling><load-balance><php>
Where to start? Scaling PHP applications on AWS
Mick
# Where to start? Scaling PHP applications on AWS

(Asked by: username_0 on 2017-09-21)

Currently all of our PHP (Laravel) applications are running on one EC2 instance. To deploy code, we SSH onto the live box and pull from CodeCommit.

We now need to scale and deploy properly.
I'm not sure where to start.

Most examples seem to use Elastic Beanstalk but I have been advised that this could be too restrictive.

I guess we want to end up with a load balancer and application servers which are created on demand.

Can anyone point me in the right direction? (I am a bit overwhelmed by all the AWS documentation.)

**Ok, this is the plan:**

I have signed up for A Cloud Guru and I'm going to work through some of the videos on there.

I'm going to sign up for a AWS Free Tier account and start tinkering.

I'm considering the *AWS Certified Solutions Architect - Associate* course, this looks like a great way to develop myself.

**Tags:** amazon-web-services, autoscaling, load-balance, php

> **Comments:**
> **username_1**: http://docs.aws.amazon.com/autoscaling/latest/userguide/WhatIsAutoScaling.html  
> **username_2**: That depends on how much you need to scale. If you are going from a single server to a thousand, it is not the same as if you are just going from a single server to two or three. If you are staying small, I would check AutoScaling, SSM (RunCommand) and / or OpsWorks  
> **username_0**: Probably 500 users max, at the moment any scaling would be better than having all the applications running on one instance. 3 servers and a load balancer would be a good start.  
> **username_3**: @username_0 - What did you end up doing?  
> **username_0**: If I had to do this now, I would probably look at the Azure App Service or similar.  

---

## 2 answers

### Answer by username_4 on 2017-09-24. Score: 3

Here's a rough approach to scaling any stateless app on AWS:

1. Run the app in an [Auto Scaling Group (ASG)](http://docs.aws.amazon.com/autoscaling/latest/userguide/AutoScalingGroup.html). An ASG makes it easy to manage multiple servers, will automatically replace failed servers, and allows you to automatically scale the number of servers up or down in response to load.
2. To run an ASG, you need to create a [Launch Configuration](http://docs.aws.amazon.com/autoscaling/latest/userguide/LaunchConfiguration.html). This is a "template" that specifies the configuration for each server in the ASG: i.e., what type of instance to run (e.g. `t2.micro`), what AMI to run on the instance, the security group settings, etc.
3. The [AMI](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) you run on each instance in the ASG should have your app already installed (i.e., your PHP app). You can define your AMI as code using a tool like [Packer](https://www.packer.io/).
4. The app in your AMI should be configured to run on boot using a process supervisor (e.g., using [systemd](https://www.freedesktop.org/wiki/Software/systemd/) or [supervisord](http://supervisord.org/); this will also ensure the app is restarted automatically if it crashes.
5. Every time you change something in your app, run a build process to create a new AMI, update the Launch Configuration to use this new AMI, and roll that AMI out across your ASG. For example, you could do a zero-downtime deployment (somewhat similar to a [blue-green deployment](https://martinfowler.com/bliki/BlueGreenDeployment.html)) by doubling the size of the ASG, waiting until all the new servers (from the updated Launch Configuration) launch and pass health checks, and then reducing the ASG back to its previous size (the ASG will terminate oldest instances by default).
6. With an ASG, you have more than one server, but you want to give your users a single endpoint to use. The typical solution to this is to deploy a load balancer in front of the ASG. If you're building a typical HTTP/HTTPs app (e.g., just about all PHP apps), you'll want to use the [Application Load Balancer (ALB)](http://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html); if you're building an app that listens directly for TCP connections, you'll want the [Load Balancer Classic](http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/introduction.html) or [Network Load Balancer](http://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html). Whichever load balancer you pick, AWS will create a domain name for it that you can use, and any requests you send to that domain name will be routed in round-robin fashion to different servers in your ASG.
7. You should a) configure the load balancer to perform health checks on your app so that it only routes to healthy servers and b) configure your ASG to register all of its servers in the load balancer automatically and to use the load balancer for health checks.
8. You can create [Auto Scaling Policies](http://docs.aws.amazon.com/autoscaling/latest/userguide/WhatIsAutoScaling.html) for the ALB that change the number of servers in your ASG depending on various CloudWatch metrics. For example, you could configure the ASG to add servers when average CPU usage is over 80% and to remove servers when CPU usage drops below 60%.

For more info, check out [A Comprehensive Guide to Building a Scalable Web App on Amazon Web Services](https://www.airpair.com/aws/posts/building-a-scalable-web-app-on-amazon-web-services-p1).

> **Comments:**
> **username_0**: Are you sure about this?: "The AMI you run on each instance in the ASG should have your app already installed ". My Manager strongly believes that the application code should not be part of the AMI. Do you have a reference for this?  
> **username_4**: @username_0 Heh, yea, pretty sure :) The approach I'm describing is called "Immutable Infrastructure".  If you google it, you'll find plenty books and blog posts on the topic (I also talk about it in my own book, *[Terraform: Up & Running](https://www.terraformupandrunning.com/)*). The idea is to create immutable, versioned images that have all of your application code baked in. You can then promote the exact same image from environment to environment and easily roll back if there is any issue. There are many ways to do it, such as using Packer to build AMIs or Docker to build Docker images.  
> **username_0**: Thanks (apologies for doubting you), I have done a bit more reading since I posted and now understand Immutable and Mutable. I'm just not sure what is best for us, we tend to do small changes and often and I'm not sure I want to build a new AMI everytime we update the code.  
> **username_0**: https://aws.amazon.com/answers/configuration-management/aws-ami-design/  
> **username_4**: @username_0 If you define your AMI using a tool like [Packer](https://www.packer.io/), then building a new AMI will be completely automated, so it's completely reasonable to build a new one after every commit. You could even extract all the dependencies that don't change often into a "base" AMI and use that as the "source" for your app AMI so the build is effectively just copying in your new code. Alternatively, look into Docker, which, due to caching, can allow you to build new images in seconds.  

---

### Answer by username_5 on 2017-09-23. Score: 1

> Currently all of our PHP (Laravel) applications are running on one EC2 instance. To deploy code, we SSH onto the live box and pull from CodeCommit.

The first thing you need to decide on is a Continuous Deploy strategy. There's a lot of servers out there with different use cases, you don't have to pick the most popular, just pick the one that fits your use case.

> I guess we want to end up with a load balancer and application servers which are created on demand.

AWS has some great reference architectures but overall I would say start simple. At a base level you'll be using Route 53, Certificate Manager, ALB (ELBv2), VPC, and EC2. I would get used to the options you have with each of these and play with them. AWS CSA will not teach you about reference architecture, rather it will go over what each product is used for.

Before you go building anything for production I would also recommend using an infrastructure deployment tool. AWS provides CloudFormation out of the box but that can be difficult to interface with. Some others are Sceptre and Terraform. These allow you to store your infrastructure as code in a repository and deploy updates via a CD server.

Also keep in mind if you don't have Continuous Integration then you'll need to work on that, followed by Continuous Delivery, then by Continuous Deployment. Each of these is a critical step in the right direction.

**Note on "Created on Demand"**

Please keep in mind that many people come to the cloud thinking that "scaling" is instantaneous. It's not. Depending on your provisioning it can take some time. You will not scale yourself out of burst traffic. Your traffic will need to be profiled, you will need to determine your instance capacity (for web servers I measure instances in requests per second with a load testing tool), and plan accordingly.

Scaling is primarily designed for a gradual rise in traffic over time, such as if your website traffic grows gradually larger around noon (peak) and then settles late in the day.


---

