Infrastructure Map — live topology
Generated from the live AWS account, not a hand-drawing — captured on 2026-07-04 with a
read-only audit profile (ali-claude) against account 140151801565 in ap-southeast-1. When infra
changes, edit the data arrays in src/components/InfraFlow / InfraMap and the diagrams redraw.
Updated 2026-08-27: added RDS jodgig-ai and the clean-room flows — jodgig.prod.cron dumps from
the replica nightly and publishes the scrubbed copy, which the AI Metabase and CloudBeaver read. See
JodGig AI Database.
How the instances talk to each other
The request flow below is derived from the live security-group rules — each arrow is a port a tier
is actually allowed to reach, not an assumption. Internet enters at one point (haproxy :443), fans out
to the frontends, which call the APIs, which alone can reach the databases and redis.
:3306/:5432 and redis :6379. haproxy in the public subnet is the single internet entry point (:443, SSL terminated). Dashed = read-replica / secondary path. Clean room (2026-08-27): jodgig.prod.cron rebuilds RDS jodgig-ai every night — dump from the replica, scrub, publish. jod.prod.metabase also runs the AI Metabase (mcp.teamjod.app → :3001) and CloudBeaver, both reading jodgig-ai only.rds-jod-test and the DMS groups allow MySQL :3306 from 0.0.0.0/0 (internet-open DB); :22 (SSH) is open to the world on many groups; 85 security groups exist, most launch-wizard-* / awseb-* cruft.ec2 describe-security-groups, 2026-07-04. e.g. prod-vpc.rds.private-subnets permits :3306 only from
10.0.128.0/20 + 10.0.144.0/20 (the private/API subnets); prod.haproxy permits :443 from
0.0.0.0/0; prod-vpc.redis.private-subnet permits :6379 only from the private subnets. On-host
processes (haproxy → nginx/php-fpm, kamal-proxy → rails, pm2) are from the deploy setup.
Inventory & cost by VPC
The same fleet, grouped by VPC/subnet with instance types and on-demand cost. Costs are on-demand list
price ($/mo at 730h) — priced at full on-demand even though the console shows $0, because NDS's
Savings Plan (not yours) currently hides it. For the money side, see
Savings Plans & cost optimisation.
140151801565 "JOD AWS 2022") is still a member of NDS's AWS Organization — management account 767010522689, org o-0iovcybjee. The self-serve migration has not completed.What the map is telling us
AWS Cost Explorer + EC2/RDS describe APIs, account 140151801565, 2026-07-04. 26 EC2 instances (25 running, 1 stopped), 11 RDS instances, 2 NAT gateways, 7 Elastic IPs. Zero Savings Plans or Reserved Instances owned by this account.
Three VPCs, two of them real. prod-vpc (10.0.0.0/16) and qa-vpc (10.1.0.0/16) mirror each
other cleanly — public subnet with an haproxy + NAT gateway in front, private subnets holding the
jodapp / jodgig / jodpro app tiers, and a private RDS subnet group behind them. The default-vpc
(172.31.0.0/16) is the odd one out: it holds only a demo box, a stopped cron, and a publicly
reachable test database — yet it is VPC-peered into both prod and qa.
rds describe-db-instances: jodapp-qa and rds-jod-test-reports both report
PubliclyAccessible=true. ec2 describe-vpc-peering-connections: pcx-07edcda1 (prod↔default)
and pcx-0040e708 (qa↔default) are both active.
The cost is lopsided toward two things. One database (jodgig, db.m7g.2xlarge) is 64% of all
RDS instance spend, and two application servers (jodgig.prod.api-2 / api-3, both c7g.2xlarge)
sit at effectively idle CPU. These are the "whale" and "rightsize" badges on the map.
CloudWatch CPUUtilization, 30-day (2026-06-04 → 07-04): jodgig.prod.api-2 avg 0.10% / max
12.6%; jodgig.prod.api-3 avg 2.68% / max 17.1% — both on 8-vCPU c7g.2xlarge. RDS jodgig
avg 20.3% / max 98.9%.
You are not billing directly with AWS yet — and NDS keeps your Savings Plan discount. This account
is still a member of NDS's AWS Organization (o-0iovcybjee). Your 25 EC2 instances read $0/hr in the
console because NDS's Savings Plan covers them from the payer account — but the NDS invoice bills you
the full on-demand rate for that same compute ($0.3332/hr for c7g.2xlarge on the May bill). The
discount is theirs, not yours. Leaving is therefore not a bill shock: you already pay on-demand.
Self-serve simply lets you buy your own Savings Plan and recapture what NDS keeps (~$180–240/mo).
NDS invoice 202605000003 (May 2026): total $2,895.42; EC2 "Compute Instance" billed entirely at
On-Demand rates ($1,135.18), matching the AWS Pricing API exactly. Meanwhile Cost Explorer shows
SavingsPlanCoveredUsage $1,097.71 canceled by SavingsPlanNegation -$1,097.71 — a payer-owned plan.
Same compute, two views: AWS covers it for NDS; NDS charges you list.
Architecture smells worth a ticket
| Smell | Where | Why it matters |
|---|---|---|
| Public databases | jodapp-qa, rds-jod-test-reports | Internet-reachable DBs on a jobs platform holding applicant data |
| Default VPC peered to prod | pcx-07edcda1, pcx-0040e708 | Flat blast radius; default VPCs should be isolated or deleted |
Idle c7g.2xlarge ×2 | jodgig.prod.api-2/3 | ~$400/mo on-demand at ~1% CPU — 2–3 sizes too big |
| gp2 storage remnants | jodgig-qa-sync, rds-jod-test-reports, 1 EBS vol | gp2 is ~20% dearer than gp3 for the same performance |
| Idle Elastic IPs | 3 unassociated + 1 on stopped box | Billable idle IPv4 (~$3.60/mo each) |
All of these are addressed with concrete numbers and a sequenced plan in Savings Plans & cost optimisation.