Network Topology
This page covers the network topology decisions set out in RAG001, RAG010, and RAG011.
VPC layout
Expand to see the subnet layout of one environment’s VPC (QA shown):
QA and Prod each own one VPC in us-east-1. The two VPCs are structurally identical and not peered. There is one Aurora Serverless v2 cluster instance in each AZ covered by the subnet group.
| Environment | VPC block | Subnet A (us-east-1a) | Subnet B (us-east-1b) |
|---|---|---|---|
| QA | 10.10.0.0/16 | 10.10.1.0/24 | 10.10.2.0/24 |
| Prod | 10.20.0.0/16 | 10.20.1.0/24 | 10.20.2.0/24 |
Blocks are non-overlapping RFC 1918 /16 prefixes. Specific values are set in each environment’s Terraform root (infra/environments/qa/ and infra/environments/prod/).
Each subnet has a local route entry only (10.x.0.0/16 local). There is no 0.0.0.0/0 or ::/0 entry. No Internet Gateway is attached. No NAT Gateway or VPC endpoint of any kind is provisioned.
| Resource type | Count | Notes |
|---|---|---|
aws_vpc | 1 per env | DNS hostnames enabled; DNS support enabled |
aws_subnet (private) | 2 per env | One per AZ; no map_public_ip_on_launch |
aws_db_subnet_group | 1 per env | Spans both subnets; used by the data module |
aws_security_group (Aurora) | 1 per env | Inbound from VPC CIDR on 5432 |
Resources absent from the module: aws_internet_gateway, aws_nat_gateway, aws_eip, aws_route_table with a public default route, aws_vpc_endpoint of any kind. The absence is intentional per RAG010.
Aurora security group
| Direction | Protocol | Port | Source | Purpose |
|---|---|---|---|---|
| Inbound | TCP | 5432 | VPC CIDR (intra-VPC) | PostgreSQL access from within the VPC |
| Outbound | All | All | 0.0.0.0/0 | AWS default; no in-VPC destination exists to reach |
The inbound rule admits nothing today because no other resource runs inside the VPC. Aurora is also reachable via the RDS Data API service endpoint, an AWS-managed HTTPS path that does not traverse the security group’s inbound rules. That path is governed by IAM (rds-data:ExecuteStatement on the cluster ARN) per RAG011.
No custom NACLs are provisioned. The default NACL applies; given the route tables carry no public routes, the NACL layer adds no meaningful control.
Service placement
Expand to see which services run inside and outside the VPC (QA shown):
Aurora is the only resource inside the VPC. Every other service runs outside the VPC and is reached from Lambda over public AWS endpoints. Lambda functions have no VPC attachment (vpc_config is not set).
Inside VPC
| Service | How reached |
|---|---|
| Aurora Serverless v2 | Subnet group spanning two AZs. RDS Data API (HTTPS, SigV4) from outside VPC; TCP/5432 unreachable from Lambda |
Outside VPC
| Service | How reached |
|---|---|
| API Lambda | Lambda execution environment. Invoked by API Gateway over AWS-managed integration |
| Authorizer Lambda | Lambda execution environment. Invoked by API Gateway on authenticated request |
| Ingestion Lambda | Lambda execution environment. Invoked by operator or CI |
| API Gateway HTTP API | AWS-managed regional. Public HTTPS endpoint; terminates the CloudFront -> API Gateway TLS connection, which is separate from the Browser -> CloudFront connection |
| CloudFront + S3 (SPA) | AWS-managed global CDN + regional object store. No VPC association; S3 access via Origin Access Control |
| AWS Bedrock (Titan, Haiku-class) | AWS-managed regional endpoint bedrock-runtime.us-east-1.amazonaws.com; IAM-authed HTTPS. The request is issued to that regional endpoint, but generation runs through a cross-region inference profile, which may execute it in any region in the us. group. The Lambda’s IAM policy grants foundation-model ARNs for every region the profile can route to (RAG007). Prompt content is NOT confined to us-east-1 |
| Secrets Manager | AWS-managed regional. secretsmanager.us-east-1.amazonaws.com; IAM-authed HTTPS |
| CloudWatch Logs and Metrics | AWS-managed regional. Public endpoint; Lambda Powertools emits structured logs and EMF metrics |
| X-Ray | AWS-managed regional. Public endpoint; Lambda Powertools instruments traces |
| RDS Data API endpoint | AWS-managed service plane. HTTPS; IAM-authed; application path into Aurora that requires no TCP from inside the VPC |
Auth and authz boundary. The Authorizer Lambda creates an authorization boundary at the API Gateway layer. API Gateway invokes it before routing any request to the API Lambda. The Authorizer Lambda calls Aurora via the RDS Data API to validate the bearer token against the key store. If the token is absent, expired, or invalid, API Gateway returns 401 or 403 and the API Lambda is never invoked. This boundary is documented as B1 in the trust boundary inventory.
On “public endpoints.” Every AWS service listed above (Bedrock, Secrets Manager, CloudWatch, X-Ray, RDS Data API) is reached by Lambda via an HTTPS endpoint with a public DNS name. These calls travel over the AWS networking fabric; they do not traverse a home-internet path, but they do use public IP space. No VPC gateway endpoint and no PrivateLink interface endpoint is provisioned. The cost rationale is in RAG010.
Cross-environment isolation
QA and Prod are separate VPCs in a single AWS account.
| Isolation property | Mechanism | Level |
|---|---|---|
| Network-layer isolation between QA and Prod | Separate VPCs; no peering; no Transit Gateway | Network |
| Data isolation | Separate Aurora clusters, Secrets Manager ARNs, S3 buckets | Resource |
| IAM isolation | Separate Lambda execution roles scoped to per-env resource ARNs | Policy |
| Terraform state isolation | Separate S3 state keys; separate S3-native lock files (per-environment) | Operational |
| Deployment gate | QA auto-deploys; Prod requires manual approval | Process |
What is not isolated at the network layer, because separation is only account-level:
- IAM namespace: a misconfigured IAM policy could grant cross-environment access. Per-env role ARNs and resource ARN conditions are the control, not network separation.
- Account-level service quotas: Lambda concurrency, Bedrock model RPM, and API Gateway throttles are account-level. A runaway QA workload can consume quota that Prod depends on.
- Bedrock model access: model availability and regional quotas are account-level, not per-VPC.
- CloudFront ACM certificate ARNs: if a wildcard certificate covers both environments, its ARN is shared across them.
- AWS Budgets alarms: billing is account-wide, and per-environment attribution depends on cost allocation tags.
The migration path to per-account isolation is documented in RAG001.
Failure modes
| Failure | Affected path | Unaffected | Mitigation / notes |
|---|---|---|---|
| Single-AZ Aurora subnet loss | RDS Data API calls during failover (~30-60 s) | Lambda, API Gateway, CloudFront, Bedrock | Aurora Serverless v2 auto-fails over to second AZ; Lambda-layer retries absorb brief window |
| Both AZs fail (regional Aurora outage) | All /query requests return 500 | API Gateway, Lambda, CloudFront + S3 (SPA still served) | No cross-region failover configured; accepted risk at demo scale |
| CloudFront edge PoP issue | SPA asset load and API requests (/query, /healthz) for affected users | API Gateway, Lambda, Aurora, Bedrock | Recovery outside operator control; no topology change resolves it |
| API Gateway throttle (burst limit) | 429 before Lambda is invoked | Aurora, Lambda execution env | 4XXError metric on API GW stage captures spike; POST /query has a route-level throttle at 1 req/s steady-state, burst 5, while GET/POST /{proxy+} is unthrottled, and it is recorded under Controls in place in the security assessment |
| Bedrock regional outage (us-east-1) | Embedding and generation; all /query requests fail | Aurora, API Gateway, Lambda invocation, CloudFront | No cross-region failover; accepted risk |
| RDS Data API unavailability | All database calls from Lambda regardless of Aurora health | Aurora TCP/5432 (unreachable from Lambda anyway) | Known constraint of the chosen data-access contract per RAG011 |
Operational surface
Runbooks: Inspecting the VPC · Log groups
When this page changes
This page must be updated when any of the following occur:
- The reversal procedure in RAG010 fires: NAT Gateway, PrivateLink endpoints, or a new in-VPC workload is introduced. The subnet layout, route tables, security group rules, and data-flow paths all change.
- RAG011 is superseded: the application data-access path to Aurora changes, which changes the query-path diagram and the service placement table.
- A new AWS service is added to the application. Add it to the service placement table.
- A second region is added. The single-region assumption in this document is pervasive.
- The AWS account separation described as a migration path in RAG001 is executed. The cross-environment isolation section changes substantially.
Changes arising from RAG010 reversal must also update architecture/cost and trigger a re-review of the security assessment and trust boundaries.
© 2026 Benjamin Arunski