Architecture
TrustMe production topology and deployment shape.
This page explains how the deployed TrustMe prototype is wired in AWS and shows a sanitized topology export generated from the live environment.
Overview
The topology export reflects the current TrustMe deployment at a systems level.
Public entry point
Route 53 resolves trustme.kettu.lol to an internet-facing application load balancer. TLS terminates at the ALB through ACM, and only the web service is exposed to public traffic.
Single app service
TrustMe runs as a TanStack Start application on ECS Fargate. The same service handles the public company page, admin interface, chat API, and AI-backed generation flows.
Private data access
Application tasks run in private subnets and connect to PostgreSQL through controlled security-group rules. Secrets and image pulls stay inside the VPC path through existing endpoints.
Deployment shape
Terraform manages the ALB, ECS service, Route 53 record, ACM certificate, IAM roles, and network rules. The application image is built locally, pushed to ECR, and then rolled out through ECS.
Request path
Browser request to TrustMe response
Route 53 maps trustme.kettu.lol to the application load balancer.
The ALB accepts HTTPS traffic, terminates TLS, and forwards healthy requests to the TrustMe target group.
The ECS Fargate service runs the TanStack Start app on port 3000.
The app renders public company pages, handles the admin UI, and serves chat and generation endpoints from the same deployment.
Database reads and writes stay behind the application layer rather than being exposed directly to the browser.
Data path
How company, review, and chat data move
Admin actions write companies, reviews, summaries, and chat history into PostgreSQL through Prisma.
The public company page reads only stored database data and never calls OpenAI during page render.
AI generation flows use OpenAI server-side and persist the generated output back into the database.
The database stays the source of truth even when AI is involved in profile, review, summary, or chat generation.
Private AWS access
How private ECS tasks reach required services
The ECS task receives DATABASE_URL and OPENAI_API_KEY from Secrets Manager.
Private networking and endpoint security-group rules allow ECS to reach Secrets Manager, ECR, and CloudWatch Logs safely.
The deployed app connects to a private PostgreSQL database without opening that database to the public internet.
One-off ECS tasks are used for Prisma migrations and database setup inside the same VPC context as the app.
Component roles
Each layer in the deployment has a narrow operational responsibility.
Edge
ALB
The application load balancer is the only public ingress layer. It handles TLS, health checks, and request forwarding to the TrustMe service.
Web app
ECS Fargate service
The TrustMe ECS service runs the TanStack Start application in production. It serves the public site, the admin UI, the chat API, and the AI-backed generation flows.
System of record
PostgreSQL / RDS
PostgreSQL stores companies, reviews, summaries, and chat messages. The application depends on it as the durable source of truth across all user-facing and AI-driven flows.
Secrets
Secrets Manager
Secrets Manager provides the deployed app with DATABASE_URL and OPENAI_API_KEY without hardcoding sensitive values into the image or Terraform files.
Container delivery
ECR
Docker images are built locally, pushed to ECR, and then selected in ECS through the Terraform-managed image tag.
Networking
VPC and endpoints
The service runs in private subnets with explicit security-group rules and shared VPC endpoints for private AWS service access. The app is public only through the ALB.
Engineering highlights
These are the decisions that make the prototype feel like a deployable product, not just a local demo.
Deployed the prototype as a real ECS Fargate service instead of leaving it as a local-only demo.
Kept the database private and used ECS-based one-off tasks for production Prisma migrations.
Separated secret management from application code by injecting DATABASE_URL and OPENAI_API_KEY from Secrets Manager.
Documented a repeatable build, push, plan, and apply flow around Terraform and ECR image tags.
Reading guide
The topology below is machine-derived from AWS and sanitized for safe sharing.
The main path to read is Route 53 to ALB to ECS to PostgreSQL. That shows the public ingress path, the application runtime, and the private data dependency.
IAM roles, VPC endpoints, and security-group references show how startup and runtime access are controlled without exposing the database or secrets publicly.
Public deployment facts
This section shows the real public-facing TrustMe values. The deeper topology export used behind this page is still redacted for safe sharing, but these identifiers are the actual deployment entry points.
Route 53 resolves trustme.kettu.lol under the kettu.lol hosted zone to the application load balancer that fronts the ECS service.
The redacted topology export remains useful for showing the dependency graph, but this summary is the place where the page should present the real TrustMe public entrypoint.
Text topology snapshot
The generated public text export for the current TrustMe deployment topology.
ROUTE53
+-------------+-------------------+------+-----------------------+----------------+----------------------+------------+
| Hosted Zone | Record | Type | Target | ALB Name | ALB DNS | Region |
+-------------+-------------------+------+-----------------------+----------------+----------------------+------------+
| kettu.lol | trustme.kettu.lol | A | alb.example.internal. | public-app-alb | alb.example.internal | eu-north-1 |
+-------------+-------------------+------+-----------------------+----------------+----------------------+------------+
ALB
+----------------+-------------+-----------------+--------+-------+--------------------+-----------------+----------------------+
| Name | Type | Scheme | State | VPC | Subnets | Security Groups | DNS |
+----------------+-------------+-----------------+--------+-------+--------------------+-----------------+----------------------+
| public-app-alb | application | internet-facing | active | vpc-1 | subnet-1, subnet-2 | sg-1 | alb.example.internal |
+----------------+-------------+-----------------+--------+-------+--------------------+-----------------+----------------------+
ALB LISTENERS
+------------+----------+------+----------------------------------------+--------------+----------------+
| Listener | Protocol | Port | Certificates | Action Types | Target Groups |
+------------+----------+------+----------------------------------------+--------------+----------------+
| listener-1 | HTTPS | 443 | arn:aws:acm:region:account:certificate | forward | target-group-1 |
| | | | /public-cert-1 | | |
+------------+----------+------+----------------------------------------+--------------+----------------+
| listener-2 | HTTP | 80 | - | redirect | - |
+------------+----------+------+----------------------------------------+--------------+----------------+
ALB LISTENER RULES
+------------+--------+----------+------------+----------+----------------+
| Listener | Rule | Priority | Conditions | Actions | Target Groups |
+------------+--------+----------+------------+----------+----------------+
| listener-1 | rule-1 | default | default | forward | target-group-1 |
+------------+--------+----------+------------+----------+----------------+
| listener-2 | rule-2 | default | default | redirect | - |
+------------+--------+----------+------------+----------+----------------+
ECS SERVICES
+-----------+-----------+---------+------------------+-------------+------------------+----------------------------------------+--------------------+-------------------------+------------------------------+---------------------------------------+----------+-----------+
| Cluster | Service | Desired | Task Definition | Task Role | Execution Role | ALB Usage | Subnets | Security Groups | SG Connections | RDS Links | S3 Links | SQS Links |
+-----------+-----------+---------+------------------+-------------+------------------+----------------------------------------+--------------------+-------------------------+------------------------------+---------------------------------------+----------+-----------+
| cluster-1 | service-1 | 1 | public-taskdef-1 | task-role-1 | execution-role-1 | public-app-alb -> target-group-1 | subnet-3, subnet-4 | security-group-2 (sg-2) | in<- security-group-1 (sg-1) | instance:db-instance-1 (sg-reference) | - | - |
| | | | | | | (container-1:3000) | | | | | | |
+-----------+-----------+---------+------------------+-------------+------------------+----------------------------------------+--------------------+-------------------------+------------------------------+---------------------------------------+----------+-----------+
IAM ROLES
+------------------+----------------------------------------+---------------+----------------------------------------+------------------+-----------------+
| Role | ARN | Path | Principal | Managed Policies | Inline Policies |
+------------------+----------------------------------------+---------------+----------------------------------------+------------------+-----------------+
| execution-role-1 | arn:aws:iam::account:role/execution-ro | /application/ | {'Service': 'ecs-tasks.amazonaws.com'} | managed-policy-1 | inline-policy-1 |
| | le-1 | | | | |
+------------------+----------------------------------------+---------------+----------------------------------------+------------------+-----------------+
| task-role-1 | arn:aws:iam::account:role/task-role-1 | /application/ | {'Service': 'ecs-tasks.amazonaws.com'} | - | - |
+------------------+----------------------------------------+---------------+----------------------------------------+------------------+-----------------+
SECURITY GROUPS
+------------------+------+-------+----------------------------------------+-------------------------+---------------------------------------+--------------------------------------+
| Name | ID | VPC | Description | Inbound Security Groups | Inbound Rules | Outbound Rules |
+------------------+------+-------+----------------------------------------+-------------------------+---------------------------------------+--------------------------------------+
| security-group-1 | sg-1 | vpc-1 | Security boundary for a demo | - | CIDR public-internet | tcp 80 | CIDR public-internet | all all ports |
| | | | component. | | CIDR public-internet | tcp 443 | |
+------------------+------+-------+----------------------------------------+-------------------------+---------------------------------------+--------------------------------------+
| security-group-2 | sg-2 | vpc-1 | Security boundary for a demo | security-group-1 (sg-1) | SG security-group-1 (sg-1) | tcp 3000 | CIDR public-internet | all all ports |
| | | | component. | | | |
+------------------+------+-------+----------------------------------------+-------------------------+---------------------------------------+--------------------------------------+
| security-group-3 | sg-3 | vpc-1 | Security boundary for a demo | security-group-2 (sg-2) | SG sg-4 (sg-4) | tcp 443 | CIDR public-internet | all all ports |
| | | | component. | sg-4 (sg-4) | SG sg-5 (sg-5) | tcp 443 | |
| | | | | sg-5 (sg-5) | SG sg-6 (sg-6) | tcp 443 | |
| | | | | sg-6 (sg-6) | SG security-group-2 (sg-2) | tcp 443 | |
+------------------+------+-------+----------------------------------------+-------------------------+---------------------------------------+--------------------------------------+
| security-group-4 | sg-7 | vpc-1 | Security boundary for a demo | security-group-2 (sg-2) | SG sg-6 (sg-6) | tcp 5432 | CIDR public-internet | all all ports |
| | | | component. | sg-4 (sg-4) | SG sg-4 (sg-4) | tcp 5432 | |
| | | | | sg-5 (sg-5) | SG sg-5 (sg-5) | tcp 5432 | |
| | | | | sg-6 (sg-6) | SG security-group-2 (sg-2) | tcp 5432 | |
+------------------+------+-------+----------------------------------------+-------------------------+---------------------------------------+--------------------------------------+
VPC ENDPOINTS
+-------------+----------------------------------------+-----------+-------+--------------------+-------------------------+-------------+-----------+
| Endpoint ID | Service | Type | VPC | Subnets | Security Groups | Private DNS | State |
+-------------+----------------------------------------+-----------+-------+--------------------+-------------------------+-------------+-----------+
| vpce-1 | com.amazonaws.eu-north-1.ecr.dkr | Interface | vpc-1 | subnet-3, subnet-4 | security-group-3 (sg-3) | true | available |
+-------------+----------------------------------------+-----------+-------+--------------------+-------------------------+-------------+-----------+
| vpce-2 | com.amazonaws.eu-north-1.logs | Interface | vpc-1 | subnet-3, subnet-4 | security-group-3 (sg-3) | true | available |
+-------------+----------------------------------------+-----------+-------+--------------------+-------------------------+-------------+-----------+
| vpce-3 | com.amazonaws.eu-north-1.secretsmanage | Interface | vpc-1 | subnet-3, subnet-4 | security-group-3 (sg-3) | true | available |
| | r | | | | | | |
+-------------+----------------------------------------+-----------+-------+--------------------+-------------------------+-------------+-----------+
| vpce-4 | com.amazonaws.eu-north-1.sqs | Interface | vpc-1 | subnet-3, subnet-4 | security-group-3 (sg-3) | true | available |
+-------------+----------------------------------------+-----------+-------+--------------------+-------------------------+-------------+-----------+
| vpce-5 | com.amazonaws.eu-north-1.ecr.api | Interface | vpc-1 | subnet-3, subnet-4 | security-group-3 (sg-3) | true | available |
+-------------+----------------------------------------+-----------+-------+--------------------+-------------------------+-------------+-----------+
| vpce-6 | com.amazonaws.eu-north-1.s3 | Gateway | vpc-1 | - | - | false | available |
+-------------+----------------------------------------+-----------+-------+--------------------+-------------------------+-------------+-----------+
RDS INSTANCES
+---------------+----------+-----------+----------------------------+-------+-------------------------+----------+
| Identifier | Engine | Status | Endpoint | VPC | Security Groups | Multi-AZ |
+---------------+----------+-----------+----------------------------+-------+-------------------------+----------+
| db-instance-1 | postgres | available | writer.db.example.internal | vpc-1 | security-group-4 (sg-7) | false |
+---------------+----------+-----------+----------------------------+-------+-------------------------+----------+
ECS TO RDS LINKS
+-------------+-------------+---------------+--------------+------------+
| ECS Service | Target Type | Target ID | Match Type | Match |
+-------------+-------------+---------------+--------------+------------+
| service-1 | instance | db-instance-1 | sg-reference | <redacted> |
+-------------+-------------+---------------+--------------+------------+
WARNINGS
- Public mode enabled: infrastructure identifiers, endpoints, ARNs, and sensitive values have been redacted.
Route 53 and ALB
The public DNS path into TrustMe.
- Hosted zone
- kettu.lol
- Record
- trustme.kettu.lol
- Record type
- A
- ALB name
- public-app-alb
- ALB DNS
- alb.example.internal
- ALB state
- active
ECS service
The application runtime behind the load balancer.
- Service name
- service-1
- Launch type
- FARGATE
- Platform
- Linux
- Desired count
- 1
- Running count
- 1
- Pending count
- 0
Database
The private PostgreSQL instance the app depends on.
- Identifier
- db-instance-1
- Engine
- postgres
- Status
- available
- Instance class
- db.t4g.micro
- Publicly accessible
- false
- Port
- 5432
Private AWS dependencies
Interface and gateway services the private ECS task path relies on.
- VPC endpoints
- 6
- Endpoint services
- api, dkr, logs, s3, secretsmanager, sqs
- IAM roles
- 2
- DB link mode
- sg-reference
- DB target type
- instance