Auto Scaling Group Uses Multiple Availability Zones
Overview
This check verifies that your EC2 Auto Scaling groups are configured to launch instances across multiple Availability Zones (AZs) within a region. Spreading instances across AZs is a foundational AWS best practice for high availability.
Risk
If all your Auto Scaling group instances run in a single Availability Zone:
- Single point of failure: An AZ outage takes down your entire application
- No automatic recovery: Auto Scaling cannot launch replacement instances if the affected AZ has capacity issues
- Increased blast radius: Problems in one zone affect 100% of your capacity instead of a fraction
Distributing across multiple AZs ensures your application stays running even when one zone experiences issues.
Remediation Steps
Prerequisites
- Access to the AWS Console with permissions to modify Auto Scaling groups
- At least two subnets in different Availability Zones within the same VPC
AWS Console Method
- Sign in to the AWS Console and navigate to EC2
- In the left navigation, scroll down to Auto Scaling and select Auto Scaling Groups
- Select the Auto Scaling group you want to update
- Go to the Details tab and click Edit in the Network section
- Under Availability Zones and subnets, add subnets from at least one additional Availability Zone
- For example, if you only have
us-east-1a, add a subnet fromus-east-1b
- For example, if you only have
- Click Update
The Auto Scaling group will now launch new instances across all selected Availability Zones.
AWS CLI (optional)
Update an Existing Auto Scaling Group
Use the update-auto-scaling-group command with multiple subnet IDs from different AZs:
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name my-asg \
--vpc-zone-identifier "subnet-abc123,subnet-def456" \
--region us-east-1
Replace:
my-asgwith your Auto Scaling group namesubnet-abc123with a subnet ID in one AZ (e.g., us-east-1a)subnet-def456with a subnet ID in a different AZ (e.g., us-east-1b)
Find Subnets in Different AZs
To list your subnets and their Availability Zones:
aws ec2 describe-subnets \
--query "Subnets[*].[SubnetId,AvailabilityZone,VpcId]" \
--output table \
--region us-east-1
Verify the Update
aws autoscaling describe-auto-scaling-groups \
--auto-scaling-group-names my-asg \
--query "AutoScalingGroups[0].[AutoScalingGroupName,AvailabilityZones,VPCZoneIdentifier]" \
--output table \
--region us-east-1
CloudFormation (optional)
CloudFormation Template
This template creates an Auto Scaling group spanning two Availability Zones:
AWSTemplateFormatVersion: '2010-09-09'
Description: Auto Scaling group with multiple Availability Zones
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC where the Auto Scaling group will be created
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: Select subnets from at least two different Availability Zones
InstanceType:
Type: String
Default: t3.micro
Description: EC2 instance type
AmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
Description: AMI ID (defaults to latest Amazon Linux 2023)
Resources:
LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateData:
InstanceType: !Ref InstanceType
ImageId: !Ref AmiId
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: multi-az-asg
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
MinSize: 2
MaxSize: 6
DesiredCapacity: 2
VPCZoneIdentifier: !Ref SubnetIds
HealthCheckType: EC2
HealthCheckGracePeriod: 300
Tags:
- Key: Name
Value: multi-az-instance
PropagateAtLaunch: true
Outputs:
AutoScalingGroupName:
Description: Name of the Auto Scaling group
Value: !Ref AutoScalingGroup
Deploy the Template
aws cloudformation deploy \
--template-file multi-az-asg.yaml \
--stack-name multi-az-asg-stack \
--parameter-overrides \
VpcId=vpc-12345678 \
SubnetIds=subnet-abc123,subnet-def456 \
--region us-east-1
Important: Select subnets from at least two different Availability Zones when deploying.
Terraform (optional)
Terraform Configuration
# Variables
variable "vpc_id" {
description = "VPC ID where resources will be created"
type = string
}
variable "subnet_ids" {
description = "List of subnet IDs from multiple AZs"
type = list(string)
}
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t3.micro"
}
# Get latest Amazon Linux 2023 AMI
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
# Launch Template
resource "aws_launch_template" "main" {
name_prefix = "multi-az-"
image_id = data.aws_ami.amazon_linux_2023.id
instance_type = var.instance_type
tag_specifications {
resource_type = "instance"
tags = {
Name = "multi-az-instance"
}
}
}
# Auto Scaling Group spanning multiple AZs
resource "aws_autoscaling_group" "main" {
name = "multi-az-asg"
min_size = 2
max_size = 6
desired_capacity = 2
vpc_zone_identifier = var.subnet_ids # Subnets from multiple AZs
health_check_type = "EC2"
health_check_grace_period = 300
launch_template {
id = aws_launch_template.main.id
version = "$Latest"
}
tag {
key = "Name"
value = "multi-az-instance"
propagate_at_launch = true
}
}
# Outputs
output "asg_name" {
description = "Name of the Auto Scaling group"
value = aws_autoscaling_group.main.name
}
output "asg_availability_zones" {
description = "Availability Zones used by the ASG"
value = aws_autoscaling_group.main.availability_zones
}
Example terraform.tfvars
vpc_id = "vpc-12345678"
subnet_ids = ["subnet-abc123", "subnet-def456"] # Must be in different AZs
Apply the Configuration
terraform init
terraform plan
terraform apply
Important: Ensure subnet_ids contains subnets from at least two different Availability Zones.
Verification
After making changes, verify your Auto Scaling group uses multiple AZs:
- In the AWS Console, go to EC2 > Auto Scaling Groups
- Select your Auto Scaling group
- Check the Details tab under Network - you should see subnets from at least two Availability Zones listed
CLI Verification
aws autoscaling describe-auto-scaling-groups \
--auto-scaling-group-names my-asg \
--query "AutoScalingGroups[0].AvailabilityZones" \
--region us-east-1
The output should show multiple AZs:
[
"us-east-1a",
"us-east-1b"
]
Additional Resources
- AWS Auto Scaling User Guide - Availability Zones
- AWS Well-Architected Framework - Reliability Pillar
- EC2 Auto Scaling Best Practices
Notes
- Minimum AZs: AWS recommends at least two AZs, but three provides even better fault tolerance
- Subnet selection: Each subnet must be in a different AZ; you cannot add multiple subnets from the same AZ to increase redundancy
- Load balancing: If using an Application Load Balancer or Network Load Balancer, ensure it is also configured to span the same AZs
- Cost consideration: Spreading across AZs does not increase costs for EC2 instances, but cross-AZ data transfer may incur charges if instances communicate across zones
- Instance distribution: By default, Auto Scaling attempts to distribute instances evenly across the specified AZs