TL;DR
Learn how to design and implement highly available architectures using AWS Elastic Load Balancing and Auto Scaling Groups for resilient applications.
Building Highly Available Architectures with AWS ELB and Auto Scaling
High availability is crucial for modern applications. This comprehensive guide will show you how to build highly available architectures using AWS Elastic Load Balancing (ELB) and Auto Scaling Groups (ASG).
$1
$1
1. Redundancy
- Multiple availability zones
- Redundant components
- No single points of failure
2. Scalability
- Horizontal scaling
- Vertical scaling
- Auto scaling capabilities
3. Fault Tolerance
- Automatic failover
- Self-healing systems
- Health monitoring
$1
$1
Multi-AZ VPC setup:
`` resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true tags = {
Name = "ha-vpc"
}
} resource "aws_subnet" "public" {
count = 3
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index] tags = {
Name = "public-subnet-${count.index + 1}"
}
}
hcl
`
$1
Application Load Balancer configuration:
` {
"Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
"Properties": {
"Name": "ha-alb",
"Subnets": ["subnet-1", "subnet-2", "subnet-3"],
"SecurityGroups": ["sg-123"],
"Scheme": "internet-facing",
"Type": "application",
"IpAddressType": "ipv4"
}
}
json
`
$1
ASG configuration with launch template:
` {
"LaunchTemplate": {
"ImageId": "ami-123456",
"InstanceType": "t3.micro",
"SecurityGroups": ["sg-123"],
"UserData": {
"Fn::Base64": {
"Fn::Join": ["", [
"#!/bin/bash\n",
"yum update -y\n",
"yum install -y httpd\n",
"systemctl start httpd\n",
"systemctl enable httpd\n"
]]
}
}
},
"AutoScalingGroup": {
"MinSize": 2,
"MaxSize": 10,
"DesiredCapacity": 2,
"HealthCheckType": "ELB",
"HealthCheckGracePeriod": 300,
"VPCZoneIdentifier": ["subnet-1", "subnet-2", "subnet-3"]
}
}
json
`
$1
$1
Create a resilient network architecture:
` resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id tags = {
Name = "main-igw"
}
} resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
} tags = {
Name = "public-rt"
}
}
hcl
`Internet Gateway
Route Tables
$1
Set up security groups:
` resource "aws_security_group" "alb" {
name = "alb-sg"
description = "Security group for ALB"
vpc_id = aws_vpc.main.id ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
} ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
} resource "aws_security_group" "instance" {
name = "instance-sg"
description = "Security group for EC2 instances"
vpc_id = aws_vpc.main.id ingress {
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
}
}
hcl
`
$1
Set up Application Load Balancer:
` resource "aws_lb" "main" {
name = "ha-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = aws_subnet.public[*].id enable_deletion_protection = true tags = {
Environment = "production"
}
} resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = "80"
protocol = "HTTP" default_action {
type = "forward"
target_group_arn = aws_lb_target_group.main.arn
}
}
hcl
`
$1
Configure Auto Scaling Group:
` resource "aws_launch_template" "main" {
name_prefix = "ha-template"
image_id = "ami-123456"
instance_type = "t3.micro" network_interfaces {
associate_public_ip_address = true
security_groups = [aws_security_group.instance.id]
} user_data = base64encode(<<-EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
EOF
)
} resource "aws_autoscaling_group" "main" {
desired_capacity = 2
max_size = 10
min_size = 2
target_group_arns = [aws_lb_target_group.main.arn]
vpc_zone_identifier = aws_subnet.public[*].id launch_template {
id = aws_launch_template.main.id
version = "$Latest"
} tag {
key = "Name"
value = "ha-instance"
propagate_at_launch = true
}
}
hcl
`
$1
$1
Configure target group health checks:
` resource "aws_lb_target_group" "main" {
name = "ha-target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id health_check {
enabled = true
healthy_threshold = 2
interval = 30
matcher = "200"
path = "/health"
port = "traffic-port"
protocol = "HTTP"
timeout = 5
unhealthy_threshold = 2
}
}
hcl
`
$1
Set up monitoring alarms:
` resource "aws_cloudwatch_metric_alarm" "high_cpu" {
alarm_name = "high-cpu-utilization"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "300"
statistic = "Average"
threshold = "80"
alarm_description = "This metric monitors EC2 CPU utilization"
alarm_actions = [aws_autoscaling_policy.scale_up.arn] dimensions = {
AutoScalingGroupName = aws_autoscaling_group.main.name
}
}
hcl
`
$1
$1
Configure target tracking:
` resource "aws_autoscaling_policy" "target_tracking" {
name = "target-tracking-policy"
autoscaling_group_name = aws_autoscaling_group.main.name
policy_type = "TargetTrackingScaling" target_tracking_configuration {
predefined_metric_specification {
predefined_metric_type = "ASGAverageCPUUtilization"
}
target_value = 50.0
}
}
hcl
`
$1
Configure step scaling:
` resource "aws_autoscaling_policy" "step_scaling" {
name = "step-scaling-policy"
autoscaling_group_name = aws_autoscaling_group.main.name
policy_type = "StepScaling"
adjustment_type = "ChangeInCapacity" step_adjustment {
scaling_adjustment = 1
metric_interval_lower_bound = 0
metric_interval_upper_bound = 20
} step_adjustment {
scaling_adjustment = 2
metric_interval_lower_bound = 20
}
}
hcl
`
$1
$1
Set up AWS Backup:
` resource "aws_backup_plan" "main" {
name = "ha-backup-plan" rule {
rule_name = "daily_backup"
target_vault_name = aws_backup_vault.main.name
schedule = "cron(0 12 * ? )" lifecycle {
delete_after = 14
}
}
}
hcl
`
$1
Configure cross-region replication:
` resource "aws_s3_bucket" "backup" {
bucket = "ha-backup-bucket"
} resource "aws_s3_bucket_replication_configuration" "replication" {
role = aws_iam_role.replication.arn
bucket = aws_s3_bucket.backup.id rule {
id = "backup-replication"
status = "Enabled" destination {
bucket = aws_s3_bucket.backup_replica.arn
storage_class = "STANDARD"
}
}
}
hcl
`
$1
$1
$1
$1
$1
$1
$1
Create monitoring dashboards:
` resource "aws_cloudwatch_dashboard" "main" {
dashboard_name = "ha-dashboard" dashboard_body = jsonencode({
widgets = [
{
type = "metric"
x = 0
y = 0
width = 12
height = 6 properties = {
metrics = [
["AWS/EC2", "CPUUtilization", "AutoScalingGroupName", aws_autoscaling_group.main.name]
]
period = 300
stat = "Average"
region = "us-west-2"
title = "CPU Utilization"
}
}
]
})
}
hcl
`
$1
Set up centralized logging:
` resource "aws_cloudwatch_log_group" "main" {
name = "/aws/ec2/ha-instances"
retention_in_days = 14
}
hcl
``
$1
Building highly available architectures requires:
Key benefits include:
$1
Why This Matters
Understanding the business and technical context helps you make informed decisions rather than blindly following patterns.
Trade-offs to Consider
Every architectural decision involves trade-offs. Consider your specific requirements, team expertise, and scale when evaluating options.
When NOT to Use This
Knowing when a solution doesn't apply is as valuable as knowing when it does. Consider alternatives for your specific situation.
Decision Framework
Use this framework to evaluate whether this approach is right for your use case based on your specific constraints and requirements.