Ultimate Web Tips
your Wordpress, jQuery, PHP, MySQL, Linux and CSS guide to a successful website
Read more:

February 8th, 2012

How to configure Auto Scaling with Amazon Web Services EC2 and ELB

Linux, by Joakim Ling.

Auto scaling with Amazon EC2 ELBUsing the Amazon Web services is a modern way to have your environment in the Cloud. It supports load balancing between your instances and thanks to Auto Scaling you’ll never need to pay for more than you use.

Basically the Auto Scaling launches additional instances to meet your demand, usually with help of a CPU alarm. Later removes them when not needed any more.

First, you need to build your environment, I would recommend having an NFS (Network File System) server, to host your web-server configuration and your web-root directory. If you need a database, have a look at Amazon RDS (Relationship Database Service), it works great as a MySQL server.

Then you will need to create an Image (Amazon AMIs), install your web-server and put all your scripts so it will automatically add itself to grant access to your NFS and so on.

That will be your Auto Scaling Image, so whenever you have a traffic spike, the Auto Scaling will launch new instances from this image.

You also need to create your Amazon ELB (Elastic Load Balancer), which can be easily done from the AWS web console under the EC2 tab.

When all this is finished, I’d recommend you install Auto Scaling Command Line Tool and Amazon CloudWatch Command Line Tool on your NFS instance.

Create a launch config

First thing you need it to create a launch config, that will tell what kind of instance will be launched.

# as-create-launch-config MyFirstConfig --image-id ami-01234567 --instance-type m1.large --key MyFirst_PairKey --group MyFirst_Group
OK-Created launch config
  • –image-id: The ID of the AMIs you created, the image with the web-server
  • –instance-type: How many virtual CPU’s and memory for the Auto Scaling images
  • –key: Which KeyPair to be used, important if you need SSH access
  • –group: The name of the Security Group, if you need special ports open

Create an Auto Scaling group

Next step will be to create your Auto Scaling group, here is where you tell minimum and maximum of instances.

# as-create-auto-scaling-group MyFirstGroup --launch-configuration MyFirstConfig --availability-zones eu-west-1a eu-west-1b --min-size 2 --max-size 20 --load-balancers MyFirstELB
OK-Created AutoScalingGroup
  • –availability-zones: Tell in which zones your instances will be launched
  • –min-size: Minimum of instances
  • –max-size: Maximum of instances

Create first policy Scale UP

We need two policies one for scaling up and one for down, in this case I will use CPU usage as alarm and when the average CPU usage is higher then 75% on all active instances it will launch two new instances.

# as-put-scaling-policy MyFirstScaleUpPolicy --auto-scaling-group MyFirstGroup --adjustment=2 --type ChangeInCapacity --cooldown 300
arn:aws:autoscaling:eu-west-1:123456789:scalingPolicy:0123456-789a-bcde-f012-3456789abcdef:autoScalingGroupName/MyFirstGroup:policyName/MyFirstScaleUpPolicy

Use the output string that the policy returned to add in your alarm.

  • –adjustment: How many instances to create when CPU usage is higher then 75%
  • –type In this case it’s capacity but percentage can also be used “PercentChangeInCapacity”
  • –cooldown Time (in seconds) between a successful scaling activity and succeeding scaling activity.
# mon-put-metric-alarm MyFirstHighCPUAlarm  --comparison-operator  GreaterThanThreshold  --evaluation-periods  1 --metric-name  CPUUtilization  --namespace "AWS/EC2" --period 600 --statistic Average --threshold  75 --alarm-actions arn:aws:autoscaling:eu-west-1:123456789:scalingPolicy:0123456-789a-bcde-f012-3456789abcdef:autoScalingGroupName/MyFirstGroup:policyName/MyFirstScaleUpPolicy --dimensions "AutoScalingGroupName=MyFirstGroup"
OK-Created Alarm
  • –comparison-operator: Tells which operator to use, in this case GreaterThanThreshold.
  • –evaluation-periods: Number of consecutive periods for which the value of the metric needs to be compared to threshold.
  • –metric-name: The name of the metric on which to alarm.
  • –namespace: A namespace for your alarms AWS/EC2 is default.
  • –period: Period of metric on which to alarm.
  • –statistic: Here we use average between periods, but others like Minimum or Maximum can be used as well.
  • –threshold: The threshold with which the metric value will be compared.
  • –alarm-actions: What should be sent, use your output from when you put your metrics alarm in previous step.
  • –dimensions: Adds a tag to all instances

Create second policy Scale Down

The down scaling policy needs to be added too. When average CPU usages goes below 20% on all instances, remove 1 instance.

# as-put-scaling-policy MyFirstScaleDownPolicy --auto-scaling-group MyFirstGroup --adjustment=-1 --type ChangeInCapacity --cooldown 300
arn:aws:autoscaling:eu-west-1:123456789:scalingPolicy:0123456-789a-bcde-f012-3456789abcdef:autoScalingGroupName/MyFirstGroup:policyName/MyFirstScaleDownPolicy
# mon-put-metric-alarm MyFirstLowCPUAlarm --comparison-operator LessThanThreshold --evaluation-periods  1 --metric-name  CPUUtilization --namespace  "AWS/EC2" --period 600 --statistic Average --threshold 20 --alarm-actions arn:aws:autoscaling:eu-west-1:123456789:scalingPolicy:0123456-789a-bcde-f012-3456789abcdef:autoScalingGroupName/MyFirstGroup:policyName/MyFirstScaleDownPolicy --dimensions "AutoScalingGroupName=MyFirstGroup"
OK-Created Alarm

Verify your configuration

# as-describe-auto-scaling-groups MyFirstGroup --headers
AUTO-SCALING-GROUP  GROUP-NAME   LAUNCH-CONFIG  AVAILABILITY-ZONES     LOAD-BALANCERS  MIN-SIZE  MAX-SIZE  DESIRED-CAPACITY
AUTO-SCALING-GROUP  MyFirstGroup  MyFirstConfig   eu-west-1a,eu-west-1b  MyFirstELB           2         20        2
INSTANCE  INSTANCE-ID  AVAILABILITY-ZONE  STATE      STATUS   LAUNCH-CONFIG
INSTANCE  i-01234567   eu-west-1a         InService  Healthy  MyFirstConfig
INSTANCE  i-01234567   eu-west-1b         InService  Healthy  MyFirstConfig

To remove your config

First you need to remove all instances from the group. Set maximum and minimum to 0. Make the auto scaling do this for you so it removes correctly from the Load Balancer.

# as-update-auto-scaling-group MyFirstGroup --min-size 0 --max-size 0
OK-Updated AutoScalingGroup

Verify in the AWS console that instances are termintated

Next step: Delete both alarms

# mon-delete-alarms MyFirstHighCPUAlarm
OK-Deleted alarms
# mon-delete-alarms MyFirstLowCPUAlarm
OK-Deleted alarms

Then delete Auto scaling group

# as-delete-auto-scaling-group MyFirstGroup
OK-Deleted AutoScalingGroup

Last step delete your config

# as-delete-launch-config MyFirstConfig
OK-Deleted launch configuration

Setting up a web server

Learn how to configure a web server from home, read more

Back Top

Club World Casinos
  • elango

    Good Job

  • elango

    I Liked the tutorials very much i saw it working in my case i dont have a loda balancer in place, so Is the CPU Utilization alarms is created for each instance in the group, or its taken average of all CPU’s in the Group, how does Amazon removes instance can you explain with an simple example …

    • http://www.ultimatewebtips.com Joakim Ling

      All alarms are an average on all instances in the group. The load balancer will direct traffic to the one with the most resources available. When an instance is removed, it’ll first remove it from the load balancer and then terminate the instance. If you are running micro instances I’d recommend to use percentage “PercentChangeInCapacity” on your alarms.

  • http://www.ubergizmo.com/hubertnguyen/ Hubert Nguyen

    I was curious to know what kind of traffic this can handle. Even a rough number would do. 

    Also, when I looked at NFS performance, I noticed that it was 10X to 15X slower than AWS EBS for simple things, like copying the whole WordPress webroot directory. 

    Normally WordPress code files should be cached in the NFS Server memory, but still, could you comment about NFS performance in a production environment? Thanks!

    • http://www.ultimatewebtips.com Joakim Ling

      I had lots of issues before I got this to work for high traffic spikes. One large instance can take about 100-500 hits/hour if cache is installed with pretty fast results. At the most I had about 50k hits/h with no problems. The only problem is that when the alarm is triggered it takes roughly 2-3 minutes before its installed and up and running. So there is a bit of “downtime” if you suddenly get a huge spike.

      Other things to think about is the database scaling, hopefully everything is cached and no queries has to be run but that’s in a perfect world :) Amazon offers something called RDS Read replicas, which is a the database auto scaling. Many times I got “Cant connect to MySQL server” or “Too many connection” before I found a good balance.

      I’m also using eAccelerator and XCache to speed up the response time. It helps a lot on the mini lag that the NFS setup creates.

      Hope that helps, I’ve used it for 2 years now, first 6 months was a bit of try and error as that was my first time I used EC2 and ELB. But now when it’s up and running I must say its very reliable.

      • http://www.ubergizmo.com/hubertnguyen/ Hubert Nguyen

        Joakim, thanks for the additional details. It’s very valuable to get some feedback form folks who are actually “in production”. 100-500 hits/hour doesn’t seem to be that much for a large instance, so I’m a bit curious about this.

        At 8 hits/sec, may I ask if you are serving static images etc with Apache, or are you using a CDN for that and all those hits are for WordPress? 
        From the sound of it, it looks like you had performance issues with the web front-end, but not with NFS itself. 

        Also, are you using the PHP acceelrators as opcode cache only, or also as an object cache for WordPress? Thanks for sharing your experience. I’m playing with WordPress and AWS, but it’s hard to have a sense of what real-world performance is.

        • http://www.ultimatewebtips.com Joakim Ling

          Yes I’m using cdn for all media, the s3 works great. I also tried the rackspace but results are more or less the same.

          I’m using w3 total cache but some of my sites can’t be cached as it’s live statistics so obviously if traffic increases on them performance is a bit bad but generally ok.

          I tried with small instances but the auto scaling went bananas and scaled up and down like crazy. Large instances are a lot more expensive but gives better performance.

          I have 2 as minimum and 20 maximum, increasing with 3 in the config.