VPC has subnets in more than one Availability Zone
VPCs are assessed for subnets spread across multiple Availability Zones. The finding distinguishes VPCs with subnets confined to a single AZ or with no subnets from those with subnets in 2+ distinct AZs.
Risk
Single-AZ subnet layouts create a single point of failure, leading to service downtime during AZ outages, maintenance, or capacity events. Lack of zonal redundancy constrains load balancing and egress design, reduces fault isolation, and undermines availability and recovery objectives.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks vpc_subnet_different_azRecommendation
Distribute subnets across 2+ Availability Zones and deploy workloads in separate AZs for high availability. Mirror network tiers per AZ, align routing and egress per AZ, and enforce multi-AZ layouts with IaC and policy guardrails. Regularly test failover to validate resilience.
Remediation
Terraform
# Create two subnets in different AZs so the VPC spans multiple Availability Zones
resource "aws_subnet" "subnet_a" {
vpc_id = "<example_resource_id>"
cidr_block = "10.0.0.0/24"
availability_zone = "<example_az_1>" # Critical: first AZ
}
resource "aws_subnet" "subnet_b" {
vpc_id = "<example_resource_id>"
cidr_block = "10.0.1.0/24"
availability_zone = "<example_az_2>" # Critical: second AZ; ensures subnets in more than one AZ
}NativeIaC
# CloudFormation: create two subnets in different AZs to ensure VPC spans multiple AZs
Resources:
SubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: <example_resource_id>
CidrBlock: 10.0.0.0/24
AvailabilityZone: <example_az_1> # Critical: place subnet in AZ1 to start AZ diversity
SubnetB:
Type: AWS::EC2::Subnet
Properties:
VpcId: <example_resource_id>
CidrBlock: 10.0.1.0/24
AvailabilityZone: <example_az_2> # Critical: second AZ ensures VPC has subnets in more than one AZOther
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.vpc.vpc_client import vpc_client
class vpc_subnet_different_az(Check):
def execute(self):
findings = []
for vpc in vpc_client.vpcs.values():
if vpc_client.provider.scan_unused_services or vpc.in_use:
report = Check_Report_AWS(metadata=self.metadata(), resource=vpc)
report.status = "FAIL"
report.status_extended = (
f"VPC {vpc.name if vpc.name else vpc.id} has no subnets."
)
if vpc.subnets:
availability_zone = None
for subnet in vpc.subnets:
if (
availability_zone
and subnet.availability_zone != availability_zone
):
report.status = "PASS"
report.status_extended = f"VPC {vpc.name if vpc.name else vpc.id} has subnets in more than one availability zone."
break
availability_zone = subnet.availability_zone
report.status_extended = f"VPC {vpc.name if vpc.name else vpc.id} has only subnets in {availability_zone}."
findings.append(report)
return findings