Separating public-facing resources from internal systems in an AWS VPC is a practical and auditable way to satisfy FAR 52.204-21 and CMMC 2.0 Level 1 Control SC.L1-B.1.XI, which require basic safeguarding of controlled unclassified information (CUI) and separation of networks; this post provides concrete VPC, subnet, route table, and security group guidance to implement that separation for a small business environment.
Design principles and compliance objectives
Your architecture should minimize internet exposure for systems that process or store CUI. Practically, that means: (1) public subnets host only resources that must have direct inbound internet access (ALBs, NAT gateways), (2) private subnets host application servers, databases, and management endpoints, and (3) tightly scoped Security Groups and restrictive network ACLs enforce least privilege. Evidence for assessors includes VPC/subnet diagrams, route table associations, security group rules, CloudTrail/Security Hub logs, and AWS Config snapshots showing rule compliance.
VPC and subnet layout: a step-by-step pattern
Use a multi-AZ, two-tier subnet strategy per AZ: one public subnet and one private subnet. Example CIDR plan for a small account: VPC 10.0.0.0/16, Public subnets 10.0.1.0/24 and 10.0.2.0/24 (AZ-a and AZ-b), Private subnets 10.0.101.0/24 and 10.0.102.0/24. Attach an Internet Gateway (IGW) to the VPC and create a route table for public subnets with 0.0.0.0/0 -> IGW. Private subnets use a different route table with 0.0.0.0/0 -> NAT Gateway (in a public subnet) so instances in private subnets initiate outbound internet traffic (patching) without direct inbound internet exposure.
Implementation details (Console and IaC)
In the AWS Console: VPC > Create VPC, then Create Subnet set to the desired AZ and CIDR. Create IGW and Attach to the VPC. Create route table for public subnet and add a route 0.0.0.0/0 to the IGW, then Associate that route table to your public subnets. Create a NAT Gateway in a public subnet (note: NAT Gateway is managed but incurs cost); create a private route table with 0.0.0.0/0 to NAT Gateway and associate it to private subnets. If cost is a concern for a tiny shop, a NAT instance (t2.micro with Source/Destination check disabled) can be used but requires manual maintenance and patching—document this tradeoff for auditors.
Security Groups and NACLs: enforce separation and least privilege
Security Groups (SGs) should be the primary access control. Example SG configuration for a 3-tier app: • ALB-SG (public): allow inbound TCP 80/443 from 0.0.0.0/0; outbound to App-SG only. • App-SG (private): allow inbound from ALB-SG on application port (e.g., 8080 or 443) and outbound to DB-SG on DB port. • DB-SG (private): allow inbound from App-SG on 5432 (Postgres) only; no inbound from internet. Do not put management ports (SSH/RDP) open to 0.0.0.0/0—restrict to corporate IPs or, better, use AWS Systems Manager (Session Manager) which removes the need to open inbound SSH and creates an auditable session log.
NACL usage and statefulness
Network ACLs are stateless and apply at the subnet level. Use NACLs for an extra layer of defense (defense-in-depth), e.g., deny known malicious IP ranges or block uncommon ports at the subnet edge. Rely on Security Groups for fine-grained instance-level controls because SGs are stateful and easier to manage. Document your NACL rules and the rationale—assessors will look for reasoning that aligns with minimizing exposure.
Supporting controls and evidence collection
Implement VPC Flow Logs for the VPC or per subnet/ENI and send them to CloudWatch Logs or S3 for retention. Enable CloudTrail for API auditing and AWS Config to enforce and record resource configuration (use managed rules like vpc-default-security-group-closed, restricted-common-ports, and required-tags). Use IAM roles for instances (EC2 instance profile) instead of embedded credentials. Produce artifacts for compliance: architecture diagrams, route table exports, Security Group screenshots/exports, CloudTrail event search for SG changes, and AWS Config compliance reports. These items demonstrate ongoing enforcement, not just a one-time build.
Real-world scenario for a small business
Scenario: a small contractor hosts a public marketing site and an internal project tracker (contains CUI). Put the marketing site behind an Application Load Balancer in public subnets with EC2 auto-scaling groups in private subnets (or behind private targets if using ALB with internal targets). The internal project tracker and its database remain in private subnets with no public IPs, accessed only via corporate VPN or Session Manager. Add an S3 VPC Endpoint for backups to avoid traffic traversing the public internet. For remote admin work, use a single bastion host with very restricted SG rules or, preferably, SSM Session Manager to reduce attack surface.
Risks of not implementing separation
If public and internal resources are not separated, you increase the risk of direct internet-based compromise (vulnerable web app leading to database exposure), lateral movement from a compromised internet-facing host into internal systems, and uncontrolled exfiltration of CUI. Non-compliance can lead to contract loss, corrective action plans, and reputational harm. From a technical standpoint, lacking proper subnet/SG separation makes detection and containment harder and generates weaker audit evidence for assessors.
Summary: design a multi-AZ VPC with designated public and private subnets, attach a single IGW and NAT Gateway pattern, enforce strict Security Group rules isolating public tiers from private tiers, enable VPC Flow Logs, CloudTrail and AWS Config for evidence, and prefer SSM over open management ports—these steps create both a defensible network posture and the documentation needed to demonstrate compliance with FAR 52.204-21 and CMMC 2.0 SC.L1-B.1.XI for a small business.