This project demonstrates how to set up an Application Load Balancer (ALB) on AWS to distribute traffic between two EC2 instances (Blue & Red servers).
It also includes optional Route 53 hosted routing, where you can configure a fake domain for demo purposes or use a real domain if you own one.
Before you begin, make sure you have:
- An AWS Account (Free Tier is enough).
- IAM user with administrator or EC2/ALB privileges.
- Basic knowledge of launching an EC2 instance.
The setup includes:
- 2 EC2 Instances: Blue server & Red server.
- Target Groups: One for each server.
- Application Load Balancer: Distributes traffic.
- Route 53 Hosted Zone (optional): For domain-based routing.
- Go to AWS Console → S3 → Create bucket.
- Enter a globally unique name: e.g.
arr-bucket-123456. - Region: us-east-1 (N. Virginia) to match the lab setup.
- Keep Block Public Access = ON (recommended).
- EC2 will use an IAM role to fetch files (not public objects).
- Click Create bucket.
- Prepare your local project so that it contains two folders:
red/andblue/, each with its ownindex.html. - In the S3 Console, open your bucket → click Upload.
- Make sure you only upload correct files & folders
- In S3 console → open your bucket → go to Properties.
- Copy the ARNs:
For example:
arn:aws:s3:::arr-bucket-123456 (bucket)
arn:aws:s3:::arr-bucket-123456/* (all objects inside)
- Create a JSON file
bucket-permissions.jsonwith:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "YOUR-BUCKET-ARN/*"
}
]
}➡ Replace YOUR-BUCKET-ARN with your actual bucket name.
- Go to IAM → Policies → Create Policy → JSON tab.
- Paste the JSON above.
- Name it: S3-ARR-Policy.
aws iam create-policy --policy-name S3-ARR-Policy --policy-document file://bucket-permissions.json- Go to IAM → Roles → Create role.
- Select AWS service → EC2.
- Attach the policy: S3-ARR-Policy.
- Name it: S3-ARR-Role.
aws iam create-role --role-name S3-ARR-Role --assume-role-policy-document file://ec2-trust-policy.json
aws iam attach-role-policy --role-name S3-ARR-Role --policy-arn arn:aws:iam::123456789012:policy/S3-ARR-PolicyName them: user-data-red and user-data-blue.
Replace YOUR-BUCKET-NAME with your actual bucket name.
Example commands:
aws s3 cp --recursive s3://arr-bucket-123456/red /var/www/html/red
aws s3 cp --recursive s3://arr-bucket-123456/blue /var/www/html/blue-
Go to EC2 → Instances → Launch Instance.
-
Choose AMI:
- Select Amazon Linux 2 AMI (Free tier eligible).
-
Instance Type:
- Choose t2.micro.
-
Key Pair:
- Proceed without a key pair or create a key pair.
-
Network Settings:
- Allow HTTP (80) and SSH (22).
-
Advanced Details:
- IAM Instance Profile: Select S3-ARR-Role.
- User Data: Paste the contents of:
user-data-red(for the Red instance), oruser-data-blue(for the Blue instance).
-
Launch Instances:
- Launch 2 instances: one Red and one Blue.
The first step is to set up the target groups; you need at least 2 target groups to configure Path-based routing.
- Go to EC2 → Target Groups under Load Balancing.
- Click Create target group.
- Set up 2 target groups:
- One called
Red-TGwhich will contain the Red targets. - One called
Blue-TGwhich will contain the Blue targets.
- One called
- Leave all defaults, except update the target group name and configure health checks:
- For Red-TG: Health check path =
/red/index.html - For Blue-TG: Health check path =
/blue/index.html
- For Red-TG: Health check path =
- Register the correct instances:
- Add the Red instance to Red-TG (be sure to click include as pending below).
- Add the Blue instance to Blue-TG (be sure to click include as pending below).
- Name:
Red-TG - Protocol: HTTP
- Port: 80
- Health Check Path:
/red/index.html - Register: Red instance
- Name:
Blue-TG - Protocol: HTTP
- Port: 80
- Health Check Path:
/blue/index.html - Register: Blue instance
- Go to EC2 → Load Balancers → Create Load Balancer → Application Load Balancer.
- Name:
ColorALB - Scheme: Internet-facing
- Listeners: HTTP on port 80
- Availability Zones: Select at least 2 subnets(the ones you used for your EC2s)
- Security Group: Allow HTTP (80)
- Target Group: Choose one (you will edit rules later)
Once ALB is active, under Listeners and rules, select the checkbox for your first listener.
Then, under the Manage Rules menu, click Add rule.
- Name and tags: Ignore and click Next.
- Conditions: Click Add condition, select Path from the dropdown menu, and enter
/red*for the path. - Actions: Forward to the Red target group.
- Priority: Set to 1.
Repeat the above creating a rule for the Blue target group:
- Path should be
/blue*. - Priority can be 2.
Test:
Copy the DNS name from the Application Load Balancer and append either /red or /blue on the URL.
You should see the different colored custom web pages we added to our instances.
http://<ALB-DNS>/red→ Red app
http://<ALB-DNS>/blue→ Blue app
- Go to Route 53 → Hosted Zones.
- Click Create Hosted Zone.
- Domain name:
mydemo.com(fake, you don’t need to own it). - Type: Public Hosted Zone.
- Click Create.
Inside your mydemo.com hosted zone:
-
Click Create Record.
- Record name:
blue(this makes itblue.mydemo.com). - Record type: A – Routes traffic to an IPv4 address or AWS resource.
- Value/Route traffic to:
- Choose Alias → Application and Classic Load Balancer.
- Region: Select the region where your ALB lives.
- Target: Select the ALB you created earlier (
ColorALB).
- Should look like this
- Click Create record.
- Record name:
-
Repeat the same steps for
red.mydemo.com:- Record name:
red. - Everything else same as above, pointing to the same ALB.
- Record name:
- Click Create Record again.
- Record name: (leave blank → this maps to
mydemo.comitself). - Record type: A.
- Alias: Yes → point to the same ALB.
- Save.
Your hosted zone will now look like this:
mydemo.com→ ALBred.mydemo.com→ ALBblue.mydemo.com→ ALB
Now that Route 53 points traffic to the ALB, we need to tell the ALB how to forward requests for each subdomain.
-
Go to EC2 → Load Balancers → Select your ALB → Listeners tab.
-
Under HTTP:80 listener, click View/edit rules.
-
Add two new rules:
- Condition: Host header =
red.mydemo.com→ Action: Forward toRed-TG. - Condition: Host header =
blue.mydemo.com→ Action: Forward toBlue-TG.
- Condition: Host header =
-
Save the rules.
Test:
http://red.mydemo.com→ Red apphttp://blue.mydemo.com→ Blue app
Even pros hit bumps on the road — here’s a quick list to keep your setup running smoothly:
Double-Check the Basics
- Did you replace YOUR-BUCKET-NAME in the user-data scripts?
- Is the IAM role S3-ARR-Role properly attached to both EC2 instances?
Files & Permissions
- Do your IAM policies cover both the bucket and bucket/* (objects inside)?
- Did you upload the correct folder structure (
red/,blue/) into your S3 bucket?
On the Instances
- Check
/var/log/cloud-init-output.logto confirm your S3 files copied over. - If the page doesn’t load, try
curl http://localhoston the instance via SSH to test locally.
At the Load Balancer Level
- Are your listener rules (path or host-based) pointing to the right target groups?
- Do your health checks show healthy targets in both groups?
Once you’re done testing the demo, it’s a good practice to delete the resources you created. This prevents unnecessary charges from running services.
Here’s what to remove:
- Application Load Balancer (ALB) – chargeable
- Amazon EC2 Instances – chargeable
- Amazon S3 bucket – chargeable
- Target Groups – not chargeable
- Security Group – not chargeable
- Amazon Route 53 Alias Records – not chargeable
Note: Always double-check before deleting resources if you’re running other projects in the same AWS account.
Congrats — you’ve just built a working Application Load Balancer demo with both path-based and host-based routing!
- You launched EC2 instances with user data scripts,
- Configured target groups with health checks,
- Set up an Application Load Balancer,
- And routed traffic smartly using rules and DNS.
If this felt a little challenging at times, that’s totally normal — you’re learning! The important part is that you now understand the pieces and how they fit together.
As you keep practicing, you can try adding new features like HTTPS, weighted routing, or auto scaling. Each step builds your confidence and gets you closer to running real-world architectures.
Well done — you took on a complex AWS service and made it work. That’s a big win!
Belinda Ntinyari – Medium | LinkedIn
This project is licensed under the MIT License.

















