Auto Scaling and Building a Full Application
Let AWS add servers at peak times, remove them when it's quiet and replace failed ones, then bring everything together into the design of a full, fault-tolerant application, and see how Elastic Beanstalk shortens the work.
- Key idea
- Definition
- When to use
- Caution
In this article
In part six we spread visitors across two servers and watched the site carry on when one failed. Two problems remain: a failed server stays failed until you step in, and the number of servers is fixed however busy or quiet things get.
Think of an online store: its night-time traffic is nothing like its traffic during a sale. Prepare servers for the peak and you pay for idle machines most of the time. Prepare fewer and the site falls over at the worst moment. The solution is an Auto Scaling group.
Auto Scaling groups (ASG)
An Auto Scaling group manages a set of servers for you. Give it a recipe and three numbers, and it handles the rest:
| Number | Meaning | Example |
|---|---|---|
| Minimum | The lowest count, however quiet it gets | 2, one in each Availability Zone |
| Desired | The count wanted right now, which changes with load | 2 |
| Maximum | The ceiling, which protects your bill | 6 |
It spreads servers across Availability Zones, registers them with the load balancer automatically, and replaces any that fail. The service itself is free; you pay only for the servers.
Launch templates
To launch servers on its own, the group needs a recipe: the system image, instance type, security group, IAM role and User Data. Everything you chose by hand in part three is saved in a template.
This is where ready-made AMIs pay off: the faster a server comes up, the faster the group responds to load.
Health checks: don't miss this option
By default, the group checks only the server itself. If the server is running but the application on it has stopped, it won't be replaced. Turn on ELB health checks so it relies on the load balancer's check, and the server gets replaced when the application itself fails.
When to grow and when to shrink
| Policy | How it works | Good for |
|---|---|---|
| Target tracking | Set a target, such as 50% average CPU, and it adjusts the count | Most cases; start here |
| Step scaling | Define steps: above 70% add one server, above 90% add three | Finer control |
| Scheduled | Add capacity at a time you set in advance | Known peaks, such as a sale starting at 8 |
| Predictive | Forecasts load from your history and prepares ahead | Load that repeats daily or weekly |
The metric you choose matters. CPU is a good start, but for websites requests per server (RequestCountPerTarget) is often more honest, because it reflects visitors directly.
To give new servers time to affect the numbers, target tracking and step policies wait out an instance warmup period. If you haven't set one, they use the default cooldown of 300 seconds.
An Auto Scaling group scales servers. If your application also has ECS services, DynamoDB tables or Aurora replicas, the AWS Auto Scaling service can manage a scaling plan for all of them in one place.
Hands-on: watch the group grow and heal itself
We'll build on the load balancer and target group from part six.
- Template: in EC2, open Launch Templates, then Create launch template. Name it
web-template, choose Amazon Linux 2023,t3.microand the servers' security group, and paste the User Data from part three. - Group: from Auto Scaling Groups, create
web-asgfrom this template, and pick two subnets in different Availability Zones. - Load balancer: choose Attach to an existing load balancer, select the target group, and turn on ELB health checks.
- Numbers: Desired 1, Minimum 1, Maximum 3.
- Policy: choose Target tracking on average CPU with a 40% target.
Sign in to the server through EC2 Instance Connect and generate CPU load. A t3.micro has two virtual CPUs, so we run two processes:
yes > /dev/null &
yes > /dev/null &
After a few minutes, see what happened from CloudShell:
# What the group did, and why
aws autoscaling describe-scaling-activities \
--auto-scaling-group-name web-asg --max-items 5 \
--query "Activities[].[StatusCode,Description]" --output table
# The current servers, their zones and health
aws autoscaling describe-auto-scaling-groups \
--auto-scaling-group-names web-asg \
--query "AutoScalingGroups[0].Instances[].[InstanceId,AvailabilityZone,HealthStatus]" \
--output table
You'll see new servers come up and join the load balancer without you touching anything. Stop the load, and after about fifteen minutes the group shrinks on its own:
pkill yes
Now the fun part: delete a server yourself and watch what happens:
aws ec2 terminate-instances --instance-ids i-0123456789abcdef0
The group notices the count has dropped below what's wanted and launches a replacement within minutes. That's an application healing itself.
Putting the pieces together: a full application
You now have all the pieces of the server tier. This is the common design for a fault-tolerant web application:
The key rule: a server is replaceable
In this design, any server can vanish at any moment: scaled in by the group, replaced after a failure, or reclaimed by Spot. So nothing important stays on it. This is what's called a stateless application. Each kind of data has its place off the server:
| Data | If you keep it on the server | The right place |
|---|---|---|
| User sessions | Users get signed out when their server changes | A shared cache such as ElastiCache |
| Uploaded files | They appear on one server and not another | S3 or EFS |
| Core data | It's lost with the server | A managed database such as RDS |
| Images and static files | Extra load on the servers | S3 with CloudFront |
We haven't reached some of these services yet; the coming sections cover them. What matters now is the idea: whenever you design something, ask "what happens if this server disappears right now?" If the answer is "nothing", you're on the right track.
The same thinking leads to immutable infrastructure: you don't update a running server. You build a new image, put it in a new launch template, and let instance refresh replace the group's servers gradually. Every server then matches what you tested, and going back means returning to the previous image.
Cost in this design
- Cover the minimum with a Savings Plan, since it runs all the time.
- Keep the extras on On-Demand or Spot.
- Review your minimum regularly; many people set it too high.
Elastic Beanstalk: the shortcut
Assembling all this by hand is work. Elastic Beanstalk does it for you: upload your code and choose the language, and it creates the load balancer, Auto Scaling group, servers and monitoring. The service itself is free; you pay for the resources it creates.
- Two common environments: one low-cost server for development, or several servers behind a load balancer for production.
- Two kinds of tier: Web Server for direct requests, Worker for processing jobs from a queue.
- Ordinary, visible resources: you can see them in your account and change them; it isn't a closed box.
It suits you if you want to focus on the code of a conventional application. If you have special requirements or many systems, you'll usually build it yourself or move to the containers covered in part twenty.
Summary
- An ASG keeps the server count between a minimum and maximum, replaces failures and works with the load balancer.
- A launch template is the server's recipe, and a ready-made AMI speeds up the response.
- Turn on ELB health checks so a server is replaced when the application itself fails.
- Start with a target tracking policy, and pick a metric that truly reflects load.
- Keep servers stateless: anything important lives off them.
Test yourself
Before you move on, try these questions to check you've got this part. Each one is a practical scenario, and the explanation appears once you answer.
Question 1 of 7
An application crashes on one server in an Auto Scaling group. The server keeps running, the load balancer marks it unhealthy, but the group doesn't replace it. What should change?
Show the answer
Correct answer: A
By default, the group looks only at the server's own status, and that's fine here. With ELB health checks on, it also treats a server the load balancer reports as failed as unhealthy, and replaces it.
- B: This allows more servers, but it doesn't replace the failed one.
- C: Scheduled actions change capacity at set times, and don't look at health.
- D: The template decides how servers launch, and the group sees no reason to launch one.
Review: Health checks in this part, and Health checks for instances in an Auto Scaling group in the AWS docs.
Question 2 of 7
A store runs a sale that starts every Friday at exactly 8 PM. Traffic jumps within minutes, and new servers need six minutes to be ready. How can the servers be ready before the rush?
Show the answer
Correct answer: C
The time is known in advance, so raise the capacity ahead of it, and leave a tracking policy to handle anything beyond that.
- A: This reacts after the load has arrived, so servers would be ready six minutes late.
- B: The maximum is only a ceiling, and it doesn't launch any servers by itself.
- D: This also reacts after the load has arrived, even with finer steps.
Review: When to grow and when to shrink in this part, and Scheduled scaling in the AWS docs.
Question 3 of 7
A web application spends most of each request waiting on an external API, so CPU stays near 20% even when requests start to pile up. A target tracking policy on CPU doesn't add servers in time. What should the policy track instead?
Show the answer
Correct answer: D
CPU doesn't reflect the load for this application. Requests per server measures the visitors directly, and it's available as a ready-made metric.
- A: CPU still wouldn't track requests, and the group would run more servers than it needs when quiet.
- B: The disk isn't what's limiting this application.
- C: This is the result of scaling, not a measure of load.
Review: When to grow and when to shrink in this part, and Target tracking policies in the AWS docs.
Question 4 of 7
An application saves users' uploads on each server's local disk. When the Auto Scaling group removes a server, those files disappear for good. What should the team do?
Show the answer
Correct answer: B
Any server in a group can disappear at any moment, so nothing important should live on it. In S3, the file is available to every server, whatever happens to any of them.
- A: The group loses the savings from scaling in, and a failed server still takes its files with it.
- C: You'd have to manage snapshots, and could still lose up to an hour of uploads.
- D: This also blocks scaling in, and doesn't protect the files from a failed server.
Review: The key rule: a server is replaceable in this part, and Make services stateless in the Well-Architected Framework.
Question 5 of 7
A small team has a conventional Python web application. It wants to upload its code and have the load balancer, Auto Scaling group and monitoring set up for it, while still being able to see and change those resources. Which service fits best?
Show the answer
Correct answer: C
Elastic Beanstalk creates these resources from your code, and they stay visible in your account. The service itself is free, and you pay for what it creates.
- A: Kubernetes takes far more to learn and run than this team needs.
- B: This scales servers, but you'd still build everything else yourself.
- D: A single server has no load balancer, no scaling, and no protection from failures.
Review: Elastic Beanstalk in this part, and What is AWS Elastic Beanstalk? in the AWS docs.
Question 6 of 7
A team patches its Auto Scaling group's servers by logging in to each one. Over time the servers have drifted apart, and rolling back a bad patch is painful. What solves both?
Show the answer
Correct answer: D
This is immutable infrastructure: nothing changes on a running server. Every server comes from the same tested image, and going back means returning to the previous one.
- A: This is faster, but servers still change while running and can still drift apart.
- B: This helps bring back one server, and doesn't keep them alike.
- C: A server's size has nothing to do with patches.
Review: The key rule: a server is replaceable in this part, and Use an instance refresh to update instances in an Auto Scaling group in the AWS docs.
Question 7 of 7
An application uses an Auto Scaling group, ECS services, DynamoDB tables and Aurora replicas. The team wants to set up scaling for all of them from one place. What fits?
Show the answer
Correct answer: A
A scaling plan can manage the capacity of all these resources in one place.
- B: This only scales the group's servers.
- C: This sets up and manages an application's environment, and doesn't gather existing services, tables and replicas into one plan.
- D: This only changes the group's size, at times you set.
Review: When to grow and when to shrink in this part, and What is a scaling plan? in the AWS docs.
That completes the high availability section. The question left is where the data lives once it's off the server. That's the next section's subject, starting in part eight with the managed databases RDS and Aurora.