🚨 CMMC Phase One started November 10! Here's everything you need to know →

Step-by-Step AWS VPC Architecture to Meet FAR 52.204-21 / CMMC 2.0 Level 1 - Control - SC.L1-B.1.XI: Isolate Public Subnetworks with Sample CloudFormation

Practical, step-by-step AWS VPC design and a reusable CloudFormation template to isolate public subnetworks so small businesses can meet FAR 52.204-21 and CMMC 2.0 Level 1 SC.L1-B.1.XI.

•
April 07, 2026
•
6 min read

Share:

Schedule Your Free Compliance Consultation

Feeling overwhelmed by compliance requirements? Not sure where to start? Get expert guidance tailored to your specific needs in just 15 minutes.

Personalized Compliance Roadmap
Expert Answers to Your Questions
No Obligation, 100% Free

Limited spots available!

This post explains how to design and deploy an AWS VPC architecture that satisfies FAR 52.204-21 and CMMC 2.0 Level 1 control SC.L1-B.1.XI — isolating public subnetworks from internal/private subnetworks — with a focused, practical CloudFormation example you can adapt for a small business environment.

What SC.L1-B.1.XI Requires and Key Objectives

At Level 1, SC.L1-B.1.XI requires organizations to isolate public subnetworks (subnets which allow inbound Internet access) from internal/private subnetworks that host Controlled Unclassified Information (CUI) or internal services; the key objectives are preventing direct Internet access to internal hosts, limiting attack surface, and ensuring that public-facing components (ALBs, NAT gateways, bastions) are the only resources exposed to 0.0.0.0/0. For implementation this means segregated route tables, tightly-scoped security groups, optional Network ACLs, and monitoring such as VPC Flow Logs and AWS Config rules to detect drift.

High-level VPC Architecture Pattern

A recommended pattern for small businesses is a 4-subnet VPC per AZ: two public subnets (one per AZ) that host ALBs, NAT Gateways, or managed services that must be Internet-facing, and two private subnets (one per AZ) that host application servers and databases with no direct route to the Internet. Public subnets get a route to an Internet Gateway (IGW); private subnets route outbound via NAT Gateway in the public subnet. Security groups should only allow 0.0.0.0/0 to reach the ALB SG and should not permit direct inbound to private instance SGs. Use SSM Session Manager for admin access instead of an Internet-accessible bastion host where possible.

Step-by-step Implementation Notes (practical)

1) Choose a VPC CIDR (e.g., 10.0.0.0/16) and split into public (10.0.0.0/24, 10.0.1.0/24) and private (10.0.2.0/24, 10.0.3.0/24) subnets across AZs. 2) Create an Internet Gateway and attach it to the VPC; associate a public route table with public subnets only. 3) Provision one Elastic IP + NAT Gateway per AZ (or use 1 NAT GW for cost savings but note HA tradeoffs) and create a private route table where 0.0.0.0/0 points to the NAT. 4) Define security groups: ALB-SG (HTTP/HTTPS from 0.0.0.0/0), App-SG (only allow ingress from ALB-SG on app ports), DB-SG (only allow ingress from App-SG). 5) Enable VPC Flow Logs to a CloudWatch Log Group or S3 and enable AWS Config rules like "restricted-common-ports" and "vpc-default-security-group-closed" to continuously evaluate compliance.

Sample CloudFormation (YAML) — deploys the pattern

The following minimal CloudFormation template creates a VPC with two public subnets, two private subnets, an IGW, a NAT Gateway, route tables and example security groups. Adapt AZ selection, CIDRs and resource counts to your environment and add outputs, tags, logging, and monitoring as needed.

AWSTemplateFormatVersion: '2010-09-09'
Description: VPC with isolated public and private subnets (sample for SC.L1-B.1.XI)
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags: [{Key: Name, Value: vpc-isolated-sample}]

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags: [{Key: Name, Value: vpc-igw}]

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags: [{Key: Name, Value: public-subnet-a}]

  PublicSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags: [{Key: Name, Value: public-subnet-b}]

  PrivateSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: false
      Tags: [{Key: Name, Value: private-subnet-a}]

  PrivateSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      MapPublicIpOnLaunch: false
      Tags: [{Key: Name, Value: private-subnet-b}]

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags: [{Key: Name, Value: public-rt}]

  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicRTAssocA:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetA
      RouteTableId: !Ref PublicRouteTable

  PublicRTAssocB:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetB
      RouteTableId: !Ref PublicRouteTable

  NatEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatEIP.AllocationId
      SubnetId: !Ref PublicSubnetA
      Tags: [{Key: Name, Value: nat-gw}]

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags: [{Key: Name, Value: private-rt}]

  PrivateRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway

  PrivateRTAssocA:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnetA
      RouteTableId: !Ref PrivateRouteTable

  PrivateRTAssocB:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnetB
      RouteTableId: !Ref PrivateRouteTable

  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: ALB SG - allows HTTP/HTTPS from Internet
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
      Tags: [{Key: Name, Value: alb-sg}]

  AppSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: App SG - only allows traffic from ALB SG
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          SourceSecurityGroupId: !Ref ALBSecurityGroup
      Tags: [{Key: Name, Value: app-sg}]

Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref VPC
  PublicSubnetA:
    Value: !Ref PublicSubnetA
  PrivateSubnetA:
    Value: !Ref PrivateSubnetA

How a Small Business Might Use This Pattern

Example: a small government contractor runs a public-facing marketing site and an internal proposal management app. Place the public web ALB in public subnets with the ALB-SG open to the Internet; app servers and the database run in private subnets with App-SG and DB-SG allowing traffic only from the ALB and other internal SGs. Admin access uses SSM Session Manager (no public SSH). This set up meets the isolation requirement: internal subnets have no direct IGW route and only limited inbound flows from explicitly allowed sources.

Compliance Tips and Best Practices

1) Tag every subnet and resource with purpose and compliance_tier so auditors can filter resources quickly. 2) Enable VPC Flow Logs and retain logs for the required retention period — stream to S3 with lifecycle rules and encryption. 3) Use AWS Config managed rules (e.g., vpc-default-security-group-closed, restricted-common-ports) and custom Config rules to detect public subnets hosting non-approved instances. 4) Prefer SSM over bastion hosts and use least-privilege IAM for engineers. 5) Regularly scan security groups for 0.0.0.0/0 openings using automated scripts or AWS Trusted Advisor/third-party tooling.

Risk of Not Isolating Public Subnetworks

Failing to isolate public subnets increases risk of direct compromise and lateral movement: if an attacker reaches an Internet-exposed instance in the same subnet as internal servers, they can pivot to databases and CUI, causing data leaks and regulatory noncompliance. For contractors under FAR 52.204-21, this could lead to audit findings, contract penalties, or loss of eligibility for sensitive work. Operationally you also risk undetected exfiltration if you lack flow logs and config tracking.

In summary, isolating public subnetworks is straightforward but essential: use separate route tables, NAT gateways for outbound from private subnets, strict security groups, VPC Flow Logs, and AWS Config to enforce and monitor the state. The provided CloudFormation template gives a practical starting point; adapt CIDRs, HA choices (multiple NATs per AZ), and logging/retention policies to match your small business's risk posture and contractual obligations under FAR and CMMC.

 

Quick & Simple

Discover Our Cybersecurity Compliance Solutions:

Whether you need to meet and maintain your compliance requirements, help your clients meet them, or verify supplier compliance we have the expertise and solution for you

 CMMC Level 1 Compliance App

CMMC Level 1 Compliance

Become compliant, provide compliance services, or verify partner compliance with CMMC Level 1 Basic Safeguarding of Covered Contractor Information Systems requirements.
 NIST SP 800-171 & CMMC Level 2 Compliance App

NIST SP 800-171 & CMMC Level 2 Compliance

Become compliant, provide compliance services, or verify partner compliance with NIST SP 800-171 and CMMC Level 2 requirements.
 HIPAA Compliance App

HIPAA Compliance

Become compliant, provide compliance services, or verify partner compliance with HIPAA security rule requirements.
 ISO 27001 Compliance App

ISO 27001 Compliance

Become compliant, provide compliance services, or verify partner compliance with ISO 27001 requirements.
 FAR 52.204-21 Compliance App

FAR 52.204-21 Compliance

Become compliant, provide compliance services, or verify partner compliance with FAR 52.204-21 Basic Safeguarding of Covered Contractor Information Systems requirements.
 
Hello! How can we help today? 😃

Chat with Lakeridge

We typically reply within minutes