Back to Checks
aws

Lambda function is configured with VPC subnets in at least two Availability Zones

awslambda_function_vpc_multi_az
Service: awslambdaSeverity: medium
OfficialBuilt-inVerified
Categories:resilience
Resource Type:AwsLambdaFunction

AWS Lambda functions attached to a VPC use subnets that span at least the required number of Availability Zones (2 by default).

The evaluation counts the unique AZs of the function's configured subnets.

Risk

Single-AZ placement limits availability. An AZ outage or subnet/IP exhaustion can block ENI creation and VPC access, causing failed invocations, timeouts, and event backlogs.

This degrades uptime and can delay processing of critical events.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks awslambda_function_vpc_multi_az

Recommendation

Distribute VPC-connected functions across subnets in 2 distinct AZs to ensure fault tolerance.

  • Choose subnets from different AZs
  • Avoid AZ-pinned configs or fixed IPs
  • Provide per-AZ egress/endpoints and routing
  • Regularly test AZ failover Aligns with resilience and defense in depth.

Remediation

CLI

aws lambda update-function-configuration --function-name <example_resource_name> --vpc-config SubnetIds=<subnet_id_az1>,<subnet_id_az2>,SecurityGroupIds=<example_security_group_id>

Terraform

resource "aws_lambda_function" "<example_resource_name>" {
  function_name = "<example_resource_name>"
  role          = "<example_role_arn>"
  handler       = "index.handler"
  runtime       = "python3.12"
  filename      = "function.zip"

  vpc_config {
    subnet_ids         = ["<subnet_id_az1>", "<subnet_id_az2>"] # Critical: subnets in different AZs
    security_group_ids = ["<example_security_group_id>"]
  }
}

NativeIaC

Resources:
  <example_resource_name>:
    Type: AWS::Lambda::Function
    Properties:
      Role: <example_role_arn>
      Handler: index.handler
      Runtime: python3.12
      Code:
        ZipFile: |
          def handler(event, context):
            return ""
      VpcConfig:
        SecurityGroupIds:
          - <example_security_group_id>
        SubnetIds:
          - <subnet_id_az1>  # Critical: select subnets in different AZs
          - <subnet_id_az2>  # Critical: ensures function operates in >=2 AZs

Other

1Open the Lambda console and select the function
2Go to Configuration > VPC > Edit
3Select the target VPC and choose at least two subnets in different Availability Zones
4Select a security group
5Click Save

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.awslambda.awslambda_client import awslambda_client
from prowler.providers.aws.services.awslambda.awslambda_function_inside_vpc.awslambda_function_inside_vpc import (
    awslambda_function_inside_vpc,
)
from prowler.providers.aws.services.vpc.vpc_client import vpc_client


class awslambda_function_vpc_multi_az(Check):
    def execute(self) -> list[Check_Report_AWS]:
        findings = []
        LAMBDA_MIN_AZS = awslambda_client.audit_config.get("lambda_min_azs", 2)
        for function_arn, function in awslambda_client.functions.items():
            # only proceed if check "awslambda_function_inside_vpc" did not run or did not FAIL to avoid to report that the function is not inside a VPC twice
            if not awslambda_client.is_failed_check(
                awslambda_function_inside_vpc.__name__,
                function_arn,
            ):
                report = Check_Report_AWS(metadata=self.metadata(), resource=function)

                report.status = "FAIL"
                report.status_extended = (
                    f"Lambda function {function.name} is not inside a VPC."
                )

                if function.vpc_id:
                    function_availability_zones = {
                        getattr(
                            vpc_client.vpc_subnets.get(subnet_id),
                            "availability_zone",
                            None,
                        )
                        for subnet_id in function.subnet_ids
                        if subnet_id in vpc_client.vpc_subnets
                    }

                    if len(function_availability_zones) >= LAMBDA_MIN_AZS:
                        report.status = "PASS"
                        report.status_extended = f"Lambda function {function.name} is inside of VPC {function.vpc_id} that spans in at least {LAMBDA_MIN_AZS} AZs: {', '.join(function_availability_zones)}."
                    else:
                        report.status_extended = f"Lambda function {function.name} is inside of VPC {function.vpc_id} that spans only in {len(function_availability_zones)} AZs: {', '.join(function_availability_zones)}. Must span in at least {LAMBDA_MIN_AZS} AZs."

                findings.append(report)

        return findings