---
title: "Network — infrastructure & VPC — N1 IT Landscape"
---

N1 IT Landscape — The Blueprint · CF-Access internal

# Network — infrastructure & VPC

N1 IT Landscape · Owner: Arun Venkataraman · source of truth: markdown SSOT

# N1 NETWORK ARCHITECTURE — FULL SPECIFICATION

> **Part of the[N1 IT Landscape](/landscape/overview/)** — the infrastructure/VPC network chapter. For who-calls-whom (service ports, stream topology, DB allow-lists) see the companion **[Network — service-to-service map](/landscape/network-services/)**. **CURRENT-STATE** as of **2026-06-09** , AWS account `191421493115`, region `us-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

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):

<figure class="visual-frame">
  <img src="/visuals/landscape/network.svg" alt="N1 network overview: Internet traffic passes Cloudflare Access and Tunnels into separate staging and production VPCs, each with private cluster and database boundaries and NAT-only egress.">
  <figcaption>Trust-boundary overview; the environment-specific CIDR, routing, and edge tables below are authoritative. <a href="/visuals/landscape/network.svg" download>Download SVG source</a></figcaption>
</figure>

  1. the layered topology (prose + ASCII),
  2. every VPC, subnet (ID, CIDR, AZ, tier), route table, gateway, peering link, and security group,
  3. the EKS networking, the data layer (Aurora + Valkey placement, endpoints, security groups),
  4. the exact ingress map (public hostname → in-cluster service:port) and the egress model,
  5. 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)

  * **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): 
    1. **Internet** — users, clinicians, developers.
    2. **Cloudflare edge** — DNS, WAF (on `n1.care`), Access (Google IdP), WARP devices, the Tunnel.
    3. **Cluster VPC** — the EKS cluster; public/NAT subnet tier + private app subnet tier.
    4. **Database VPC** — isolated; Aurora + Valkey only; reachable from the cluster VPC over peering.
  * **Ingress rule (critical):** the only inbound path is a **Cloudflare Tunnel**. `cloudflared` pods inside the cluster open an **outbound** connection to Cloudflare; Cloudflare forwards request traffic down that connection to in-cluster `ClusterIP` services. 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 by `kubectl`, 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 **`/18` private "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 sets `MapPublicIpOnLaunch` (no workload gets a public IP).
  * **Database VPC:** three **`/24` private 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

### 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)

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)

`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

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

### 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)

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)

`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

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

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

  * **Boundary: Internet** — `users` (clinicians/developers).
  * **Boundary: Cloudflare edge** — `cloudflare_dns`, `cloudflare_access` (Google IdP), `cloudflare_waf` (production/`n1.care` only), `warp_devices`, `tunnel` (`{EKS Staging|EKS Production}`).
  * **Boundary: Cluster VPC`{cidr}`**
    * tier _NAT/public_ : `igw`, `nat_gw` (in `2a`), three `/24` subnets `{a,b,c}`.
    * tier _private app_ : three `/18` subnets `{a,b,c}`.
    * `eks_cluster` (control plane, public+private API endpoint), `karpenter`, `nodes` (Bottlerocket).
    * workload group `cloudflared` (kube-system) and `cluster_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-only `api-proxy/auth-proxy/billing-proxy`, `pdf-converter`).
  * **Boundary: Database VPC`{cidr}`** — three `/24` subnets, `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`)

  1. `users → cloudflare_dns` : `HTTPS`
  2. `cloudflare_access → cloudflare_dns` : `gate (Google IdP, @n1.healthcare)`
  3. `cloudflare_waf → cloudflare_dns` : `WAF (Managed+OWASP, n1.care)` _(production)_
  4. `cloudflare_dns → tunnel` : `route hostname`
  5. `cloudflared → tunnel` : `outbound connection (cloudflared dials OUT)` — **draw arrow from cluster to Cloudflare; no inbound ports**
  6. `tunnel → cluster_services` : per ingress map, label each `hostname → service:port/proto`
  7. `eks_cluster → users` : `public API-server endpoint (IAM/OIDC auth, 0.0.0.0/0)` — control-plane path
  8. `cluster_services → nat_gw` : `egress`
  9. `nat_gw → igw` : ``
  10. `igw → {vertex_ai, stripe, postmark, github, ecr, r2, dhi_io, aws_apis}` : `internet egress (no VPC endpoints)`
  11. `private_app_subnets → database VPC` : `VPC peering {pcx-id}`
  12. `cluster_services → aurora` : `PostgreSQL 5432 (via pgbouncer)` across peering
  13. `cluster_services → valkey` : `Valkey/Redis 6379` across peering
  14. `warp_devices → aurora` : `db.staging.n1 (Gateway DNS override, WARP only, read-only)` _(staging only, inferred private route)_
  15. `warp_devices → valkey` : `redis.staging.n1 (Gateway DNS override, WARP only, read-only)` _(staging only, inferred)_

### 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

  * 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 `5432` and ↔ Valkey `6379` across the peering link, gated by the database `*-rds-sg` security group.
  * The **AI/development cluster** (`n1-ai-cluster`, account `083636777616`) is out of scope and not shown; it follows the same NAT-only-egress + Cloudflare-tunnel-ingress pattern.
