Network — infrastructure & VPC — N1 IT Landscape
N1 IT Landscape — The Blueprint · CF-Access internal
Network — infrastructure & VPC
Section titled “Network — infrastructure & VPC”N1 IT Landscape · Owner: Arun Venkataraman · source of truth: markdown SSOT
N1 NETWORK ARCHITECTURE — FULL SPECIFICATION
Section titled “N1 NETWORK ARCHITECTURE — FULL SPECIFICATION”Part of theN1 IT Landscape — the infrastructure/VPC network chapter. For who-calls-whom (service ports, stream topology, DB allow-lists) see the companion Network — service-to-service map. CURRENT-STATE as of 2026-06-09 , AWS account
191421493115, regionus-east-2. Inventoried live (aws ec2/eks/rds/elasticache, Cloudflare API). All facts are verified except the two points explicitly marked (inferred).
How to use this file
Section titled “How to use this file”This document is written so that a person or an AI can reconstruct N1’s network diagrams in full depth from the text alone. It gives, for each environment (staging and production):
- the layered topology (prose + ASCII),
- every VPC, subnet (ID, CIDR, AZ, tier), route table, gateway, peering link, and security group,
- the EKS networking, the data layer (Aurora + Valkey placement, endpoints, security groups),
- the exact ingress map (public hostname → in-cluster service:port) and the egress model,
- a diagram source record : an explicit node list and edge list with labels and trust-boundary groupings. It is retained as historical input for the versioned visual source, not as browser-rendered diagram code.
The published overview groups nodes by the trust boundaries in §1, places the Cloudflare edge above the cluster VPC and its private database VPC, and keeps staging and production as separate, non-connected graphs. The edge list remains the detailed source record.
1. Global model (applies to both environments)
Section titled “1. Global model (applies to both environments)”- One AWS account (
191421493115), one region (us-east-2), three Availability Zones (us-east-2a/2b/2c). Staging and production are fully separate VPCs and never talk to each other. - Trust boundaries (use these as diagram groupings, outermost → innermost):
- Internet — users, clinicians, developers.
- Cloudflare edge — DNS, WAF (on
n1.care), Access (Google IdP), WARP devices, the Tunnel. - Cluster VPC — the EKS cluster; public/NAT subnet tier + private app subnet tier.
- Database VPC — isolated; Aurora + Valkey only; reachable from the cluster VPC over peering.
- Ingress rule (critical): the only inbound path is a Cloudflare Tunnel.
cloudflaredpods inside the cluster open an outbound connection to Cloudflare; Cloudflare forwards request traffic down that connection to in-clusterClusterIPservices. Therefore AWS has no inbound ports, no public IPs on workloads, no load balancers, and no ACM certificates. TLS terminates at Cloudflare. - EKS API-server exception: the Kubernetes API-server endpoint is public (
endpointPublicAccess = true,publicAccessCidrs = 0.0.0.0/0) and private; it is authenticated by AWS IAM/OIDC. This is a separate control-plane path from application traffic, used bykubectl, ArgoCD, Karpenter, CI. - Egress rule: pods reach the internet through a single NAT gateway per cluster VPC (in
us-east-2a) → internet gateway. There are no VPC endpoints , so traffic to AWS APIs (S3, ECR, Secrets Manager, STS) and to external services (GCP Vertex AI, Stripe, Postmark, GitHub, Cloudflare R2,dhi.io) all egresses via NAT. - Subnet tiers (per cluster VPC): three large
/18private “app” subnets (one per AZ) host the EKS nodes/pods and route egress through NAT; three small/24“NAT/public” subnets (one per AZ) carry the route to the internet gateway and host the NAT gateway. No subnet setsMapPublicIpOnLaunch(no workload gets a public IP). - Database VPC: three
/24private subnets (one per AZ); a route table sends the cluster-VPC CIDR back over the peering link; RDS and ElastiCache both live here in their own subnet groups.
2. STAGING
Section titled “2. STAGING”2.1 Topology (ASCII)
Section titled “2.1 Topology (ASCII)” INTERNET — users · developers │ HTTPS ┌─────────────────────────────┴──────────────────────────────┐ │ CLOUDFLARE edge │ │ Access (Google IdP @n1.healthcare) · WARP · DNS │ │ Tunnel "EKS Staging" id=03dae21f (healthy, 8 conns) │ └─────────────────────────────┬──────────────────────────────┘ outbound tunnel (cloudflared dials OUT) — no inbound ports ▼ ┌──────── VPC n1-staging-cluster-vpc vpc-0e8b4e1cc854393cd 10.10.0.0/16 ────────┐ │ NAT/public tier (/24, route→IGW igw-0a9175f4684f99808): │ │ 2a subnet-0b6800f4ed3c6fb37 10.10.192.0/24 (NAT gw nat-0fa14ebecfd9b4311) │ │ 2b subnet-06b8b97c7a6e2346f 10.10.193.0/24 │ │ 2c subnet-0b3e7427f03afac8e 10.10.194.0/24 │ │ Private app tier (/18, route→NAT + peering→10.80): │ │ 2a subnet-0f79867baf12c5efe 10.10.0.0/18 │ │ 2b subnet-01c421077f2dbd594 10.10.64.0/18 │ │ 2c subnet-0c64caa054fcd318f 10.10.128.0/18 │ │ EKS n1-staging-cluster (k8s v1.35.4) — 12 Bottlerocket nodes, Karpenter │ │ cluster SG sg-04733424b4539086e · node SG sg-028257ce022982ce4 · │ │ control-plane ENI SG (eks-cluster-sg) sg-0017610cc00c6e9f8 │ │ cloudflared ×2 (kube-system) ─serves─▶ ClusterIP services (see ingress map) │ │ egress ─▶ NAT (2a) ─▶ IGW ─▶ internet (Vertex AI, Stripe, Postmark, GitHub, │ │ ECR, R2, dhi.io, AWS APIs) │ └───────────────────────────────────────┬─────────────────────────────────────────┘ peering pcx-0b0be34847a25cce8 (active) ┌───────────────────────────────────────▼──── VPC n1-staging-database vpc-08b5430d41c64a4e5 10.80.0.0/16 ──┐ │ Private subnets (/24): 2a 10.80.1.0/24 subnet-0d22f082a83393d05 · │ │ 2b 10.80.2.0/24 subnet-01545530e79cf6b90 · │ │ 2c 10.80.3.0/24 subnet-0040aab6f7695227b │ │ RDS SG sg-0ec302e948493a190 (n1-staging-database-rds-sg) · subnet group n1-staging-database-subnet-group│ │ Aurora PostgreSQL 17.7 Serverless v2 clusters (endpoint host …cluster-c3gc6ccoiwig.us-east-2.rds…): │ │ n1-staging-app · auth-staging · billing-staging · litellm-staging · forge-runner-staging (agno) │ │ ElastiCache Valkey 8.2.0 — replication group staging-valkey (2× cache.r7g.xlarge, auto-failover); │ │ subnet group "staging-valkey"; endpoint staging-valkey.zc3ep9.ng.0001.use2.cache.amazonaws.com │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Developer read-only access (WARP-enrolled @n1.healthcare devices only): db.staging.n1 → (Cloudflare Gateway DNS override) → n1-staging-app.cluster-c3gc6ccoiwig.us-east-2.rds.amazonaws.com redis.staging.n1 → (Cloudflare Gateway DNS override) → staging-valkey.zc3ep9.ng.0001.use2.cache.amazonaws.com The DNS override returns the private RDS/Valkey host; the device reaches it over the tunnel's private-network route into 10.80.0.0/16 (inferred).2.2 Route tables (staging)
Section titled “2.2 Route tables (staging)”| VPC | Route table | Routes |
|---|---|---|
cluster 10.10.0.0/16 |
rtb-0946754c442477fb7 (public/NAT tier) |
10.10.0.0/16→local · 0.0.0.0/0→IGW igw-0a9175f4684f99808 |
| cluster | rtb-08750244c638b557e (private app tier) |
10.10.0.0/16→local · 10.80.0.0/16→peering pcx-0b0be348 · 0.0.0.0/0→NAT nat-0fa14ebecfd9b4311 |
| cluster | rtb-06d7d8f31b18f8446 |
10.10.0.0/16→local (isolated) |
database 10.80.0.0/16 |
rtb-081c9057abce4d76b |
10.10.0.0/16→peering · 10.80.0.0/16→local |
| database | rtb-0b48e600a87cd3a3d |
10.80.0.0/16→local |
2.3 EKS networking (staging)
Section titled “2.3 EKS networking (staging)”vpc-0e8b4e1cc854393cd; control-plane subnets subnet-0f79867baf12c5efe, subnet-01c421077f2dbd594, subnet-0c64caa054fcd318f (the three /18); cluster SG sg-04733424b4539086e; cluster-created ENI SG sg-0017610cc00c6e9f8; endpoint public + private , public CIDR 0.0.0.0/0.
2.4 Ingress map (staging) — public hostname → in-cluster backend
Section titled “2.4 Ingress map (staging) — public hostname → in-cluster backend”| Public hostname | Backend service.namespace:port |
Protocol |
|---|---|---|
api-staging.n1.care |
api-websocket-proxy.staging:9999 |
WebSocket |
api-staging.n1.care |
oathkeeper-proxy.staging:4455 |
HTTP (→ api-backend) |
auth-staging.n1.care |
authentication-service.staging:9000 and kratos-public.staging:4433 |
HTTP |
oauth-staging.n1.care |
hydra-public.staging:4444 |
HTTP |
billing-staging.n1.care |
oathkeeper-proxy.staging:4455 |
HTTP |
staging-admin.n1-research.com |
admin-dashboard.staging:3000 |
HTTP |
argocd-staging.n1-research.com |
argocd-server-proxy.argocd:443 |
HTTPS |
automated-testing.n1-research.com |
automated-testing.staging:8787 |
HTTP |
litellm-staging.n1-research.com |
litellm.llmproxy:4000 |
HTTP |
3. PRODUCTION
Section titled “3. PRODUCTION”3.1 Topology (ASCII)
Section titled “3.1 Topology (ASCII)” INTERNET — clinicians (app.n1.care) │ HTTPS ┌─────────────────────────────┴──────────────────────────────┐ │ CLOUDFLARE edge │ │ WAF (n1.care: Managed + OWASP) · Access · WARP · DNS │ │ Tunnel "EKS Production" id=5a3b0a66 (healthy, 8 conns) │ └─────────────────────────────┬──────────────────────────────┘ outbound tunnel (cloudflared dials OUT) — no inbound ports ▼ ┌──────── VPC n1-production-cluster-vpc vpc-02bfbd3ac089cc6cc 10.30.0.0/16 ────────┐ │ NAT/public tier (/24, route→IGW igw-00af27c9514cf1077): │ │ 2a subnet-036709bb3487c205f 10.30.192.0/24 (NAT gw nat-0b0e21a37fb950920) │ │ 2b subnet-0efa880dd7c33ae39 10.30.193.0/24 │ │ 2c subnet-0481a253a6b8d06b7 10.30.194.0/24 │ │ Private app tier (/18, route→NAT + peering→10.70): │ │ 2a subnet-0f32faa0c3b22e0eb 10.30.0.0/18 │ │ 2b subnet-0b78705a0735f6ccb 10.30.64.0/18 │ │ 2c subnet-0c2d73517db3edfa6 10.30.128.0/18 │ │ EKS n1-production-cluster (k8s v1.35.4) — 10 Bottlerocket nodes, Karpenter │ │ cluster SG sg-078566499446bdb22 · node SG sg-09dbb3a8b57a373b8 · │ │ control-plane ENI SG (eks-cluster-sg) sg-07474adb47a3bf828 │ │ cloudflared ×2 (kube-system) ─serves─▶ ClusterIP services (see ingress map) │ │ egress ─▶ NAT (2a) ─▶ IGW ─▶ internet (Vertex AI, Stripe, Postmark, GitHub, │ │ ECR, R2, dhi.io, AWS APIs) │ └───────────────────────────────────────┬─────────────────────────────────────────┘ peering pcx-043ae3b00da8e9703 (active) ┌───────────────────────────────────────▼──── VPC n1-production-database vpc-039f3b070cb9de124 10.70.0.0/16 ┐ │ Private subnets (/24): 2a 10.70.1.0/24 subnet-0838b2e33986b75ff · │ │ 2b 10.70.2.0/24 subnet-0793491a194679826 · │ │ 2c 10.70.3.0/24 subnet-069819557be80e753 │ │ RDS SG sg-09a9f6eba199245f6 (n1-production-database-rds-sg) · subnet group n1-production-database-subnet-group │ Aurora PostgreSQL 17.7 Serverless v2 clusters (endpoint host …cluster-c3gc6ccoiwig.us-east-2.rds…): │ │ n1-production-app · auth-production · billing-production (**Multi-AZ**) · litellm-production · │ │ forge-runner-production (agno) │ │ ElastiCache Valkey 8.2.0 — replication group production-valkey (2× cache.m7g.large, auto-failover); │ │ subnet group "production-valkey" │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Production databases are NOT exposed to developers (no WARP DNS override exists for production).3.2 Route tables (production)
Section titled “3.2 Route tables (production)”| VPC | Route table | Routes |
|---|---|---|
cluster 10.30.0.0/16 |
rtb-0aa3632231c49bd5c (public/NAT tier) |
10.30.0.0/16→local · 0.0.0.0/0→IGW igw-00af27c9514cf1077 |
| cluster | rtb-0e99547a1c5367517 (private app tier) |
10.30.0.0/16→local · 10.70.0.0/16→peering pcx-043ae3b0 · 0.0.0.0/0→NAT nat-0b0e21a37fb950920 |
| cluster | rtb-0200630a80c27991c |
10.30.0.0/16→local (isolated) |
database 10.70.0.0/16 |
rtb-0e7f3e63d6d309d14 |
10.30.0.0/16→peering · 10.70.0.0/16→local |
| database | rtb-062940b2dd768da07 |
10.70.0.0/16→local |
3.3 EKS networking (production)
Section titled “3.3 EKS networking (production)”vpc-02bfbd3ac089cc6cc; control-plane subnets subnet-0f32faa0c3b22e0eb, subnet-0b78705a0735f6ccb, subnet-0c2d73517db3edfa6 (the three /18); cluster SG sg-078566499446bdb22; cluster-created ENI SG sg-07474adb47a3bf828; endpoint public + private , public CIDR 0.0.0.0/0.
3.4 Ingress map (production) — public hostname → in-cluster backend
Section titled “3.4 Ingress map (production) — public hostname → in-cluster backend”| Public hostname | Backend service.namespace:port |
Protocol |
|---|---|---|
api.n1.care / api-production.n1.care |
api-websocket-proxy.prod:9999 |
WebSocket |
api.n1.care / api-production.n1.care |
oathkeeper-proxy.prod:4455 |
HTTP (→ api-backend) |
auth.n1.care / auth-production.n1.care |
authentication-service.prod:9000 and kratos-public.prod:4433 |
HTTP |
oauth.n1.care |
hydra-public.prod:4444 |
HTTP |
billing.n1.care / billing-production.n1.care |
oathkeeper-proxy.prod:4455 |
HTTP |
admin.n1-research.com |
admin-dashboard.prod:3000 |
HTTP |
argocd.n1-research.com |
argocd-server-proxy.argocd:443 |
HTTPS |
litellm-prod.n1-research.com |
litellm.llmproxy:4000 |
HTTP |
4. DIAGRAM-GENERATION SPEC
Section titled “4. DIAGRAM-GENERATION SPEC”This is the same topology expressed as a node/edge list, so a tool can lay it out automatically. Build two separate graphs (staging, production); they share shape, differing only in the values in §2/§3. Substitute {env} and the per-env IDs/CIDRs from above.
4.1 Nodes (per environment), grouped by trust boundary
Section titled “4.1 Nodes (per environment), grouped by trust boundary”- Boundary: Internet —
users(clinicians/developers). - Boundary: Cloudflare edge —
cloudflare_dns,cloudflare_access(Google IdP),cloudflare_waf(production/n1.careonly),warp_devices,tunnel({EKS Staging|EKS Production}). - Boundary: Cluster VPC
{cidr}- tier NAT/public :
igw,nat_gw(in2a), three/24subnets{a,b,c}. - tier private app : three
/18subnets{a,b,c}. eks_cluster(control plane, public+private API endpoint),karpenter,nodes(Bottlerocket).- workload group
cloudflared(kube-system) andcluster_services(the ClusterIP services from the ingress map:api-websocket-proxy,oathkeeper,api-backend,authentication-service,kratos,hydra,admin-dashboard,phoenix-router,phoenix-parser,rosetta-grouper,forge-sentinel,forge-agents-api,litellm,mineru,otel,argocd, plus prod-onlyapi-proxy/auth-proxy/billing-proxy,pdf-converter).
- tier NAT/public :
- Boundary: Database VPC
{cidr}— three/24subnets,rds_sg,aurora(5 clusters),valkey(2-node replication group). - External egress targets (outside all boundaries):
vertex_ai,stripe,postmark,github,ecr,r2,dhi_io,aws_apis.
4.2 Edges (directed; label)
Section titled “4.2 Edges (directed; label)”users → cloudflare_dns:HTTPScloudflare_access → cloudflare_dns:gate (Google IdP, @n1.healthcare)cloudflare_waf → cloudflare_dns:WAF (Managed+OWASP, n1.care)(production)cloudflare_dns → tunnel:route hostnamecloudflared → tunnel:outbound connection (cloudflared dials OUT)— draw arrow from cluster to Cloudflare; no inbound portstunnel → cluster_services: per ingress map, label eachhostname → service:port/protoeks_cluster → users:public API-server endpoint (IAM/OIDC auth, 0.0.0.0/0)— control-plane pathcluster_services → nat_gw:egressnat_gw → igw: ``igw → {vertex_ai, stripe, postmark, github, ecr, r2, dhi_io, aws_apis}:internet egress (no VPC endpoints)private_app_subnets → database VPC:VPC peering {pcx-id}cluster_services → aurora:PostgreSQL 5432 (via pgbouncer)across peeringcluster_services → valkey:Valkey/Redis 6379across peeringwarp_devices → aurora:db.staging.n1 (Gateway DNS override, WARP only, read-only)(staging only, inferred private route)warp_devices → valkey:redis.staging.n1 (Gateway DNS override, WARP only, read-only)(staging only, inferred)
4.3 Published visual source
Section titled “4.3 Published visual source”The versioned SVG overview above is the published diagram. The node and edge lists in §§4.1–4.2 remain the complete implementation record.
5. Notes & boundaries of this document
Section titled “5. Notes & boundaries of this document”- Everything is verified live except: the WARP→database private-network route (the Gateway DNS override is verified; the underlying tunnel private-route that carries the connection is inferred).
- No VPC endpoints exist , so all AWS-API and external egress is over NAT (this is a deliberate part of the picture, not an omission).
- Security-group rules (allowed ports between SGs) were not enumerated here — only SG identities and purposes. The effective paths are: cluster nodes ↔ Aurora
5432and ↔ Valkey6379across the peering link, gated by the database*-rds-sgsecurity group. - The AI/development cluster (
n1-ai-cluster, account083636777616) is out of scope and not shown; it follows the same NAT-only-egress + Cloudflare-tunnel-ingress pattern.
