Skip to main content

Network & DNS

AIQLick runs in eu-north-1 (Stockholm). The post-Phase-7 layout puts all backend + AI traffic behind a public ALB with ECS Fargate tasks in private subnets; the only public-IP workloads left are the Jitsi EC2 and a separate support-backend-alb. DNS is managed externally on one.com (no Route 53).

VPC Configuration

PropertyValue
VPCDefault VPC
CIDR172.31.0.0/16
Regioneu-north-1 (Stockholm)
Public subnetsDefault /20s across 3 AZs (172.31.0.0/20, 172.31.16.0/20, 172.31.32.0/20)
Private subnets172.31.96.0/20 (AZ-A), 172.31.112.0/20 (AZ-B), 172.31.128.0/20 (AZ-C)
Internet GatewayDefault (attached to VPC)
NAT GatewayOne in AZ-A (aiqlick-nat-eu-north-1a) — egress for cross-region eu-west-1 calls (Rekognition / Transcribe / Polly)
VPC endpoints9 Interface (ecr.api, ecr.dkr, logs, secretsmanager, sqs, sns, events, appconfig, appconfigdata, bedrock-runtime) + 1 S3 Gateway

Private subnets host every ECS Fargate task (backend + BG dev/prod). Public subnets host the public ALB, the NAT gateway, and the Jitsi EC2. The four legacy backend/AI EC2s that previously also lived in the public subnets were terminated in the Phase 7 cleanup of 2026-05-14.

Load balancers

ALBSchemeListenerCertPurpose
aiqlick-public-albinternet-facingHTTPS:443 + HTTP:80 (plain forward)ACM api.aiqlick.com SAN api-dev.aiqlick.com (eu-north-1, 644abb95-…)Public backend traffic. Host-header rules: api.aiqlick.comtg-backend-prod, api-dev.aiqlick.comtg-backend-dev.
aiqlick-internal-albinternalHTTP:80None (private VPC, internal-service JWT auth)Backend → BG. Host-header rules: bg-prod.aiqlick.localtg-bg-prod, bg-dev.aiqlick.localtg-bg-dev.
support-backend-albinternet-facing(per support-backend-rust setup)(per support-backend-rust setup)Standalone Rust support-backend service. Documented in support-backend-rust/CLAUDE.md.

Sticky sessions are enabled on the public ALB (lb_cookie, 1h) for WebSocket subscriptions and SSE — without them a client reconnect under load lands on a different task and loses the in-process subscription state.

Security Groups

The post-Phase-7 SG layout enforces direction-of-flow:

public-alb-sg   :443 ← 0.0.0.0/0

ecs-backend-sg :4001 ← public-alb-sg

internal-alb-sg :80 ← ecs-backend-sg

ecs-bg-sg :8000 ← internal-alb-sg
SGIngressNotes
aiqlick-public-alb-sg:443 ← 0.0.0.0/0, :80 ← 0.0.0.0/0Public ALB
aiqlick-ecs-backend-sg:4001 ← aiqlick-public-alb-sgECS backend tasks
aiqlick-internal-alb-sg:80 ← aiqlick-ecs-backend-sgInternal ALB
aiqlick-ecs-bg-sg:8000 ← aiqlick-internal-alb-sg, :8000 ← aiqlick-ecs-backend-sg (direct, fallback for Cloud Map name resolution to task ENI)ECS bg-tasks
aiqlick-vpc-endpoint-sg:443 ← 172.31.0.0/16Interface endpoints
jitsi-sgTCP :22 / :80 / :443, UDP :10000 (JVB media), UDP :20000-20050 (Jigasi RTP)Jitsi EC2
aiqlick-elasticache-sg:6379 ← 172.31.0.0/16Reserved — primary Redis is Redis Cloud (external), this SG is unused today.

The legacy aiqlick-backend-sg and aiqlick-ai-dev-private-sg were deleted in the Phase 7 cleanup of 2026-05-14 along with the four EC2 hosts they protected.

DNS Configuration

All aiqlick.com records live in one.com. There is no Route 53 public zone. Records point at the public ALB DNS, Amplify endpoints, CloudFront distributions, or (for legacy reasons) directly at EC2 public IPs.

DomainTypeTargetService
api.aiqlick.comCNAMEaiqlick-public-alb-2032682590.eu-north-1.elb.amazonaws.comBackend prod (ECS Fargate via host-header rule)
api-dev.aiqlick.comCNAMEaiqlick-public-alb-2032682590.eu-north-1.elb.amazonaws.comBackend dev (ECS Fargate via host-header rule)
ai.aiqlick.com(deleted 2026-05-14)one.com parking 46.30.213.40Record removed from one.com after the Phase 7 cleanup. The bare hostname now falls through to one.com's parking response (Apache 500) — normal one.com behavior for any unconfigured subdomain on a one.com-hosted zone.
ai-dev.aiqlick.com(deleted 2026-05-14)one.com parking 46.30.213.40Same disposition as ai.aiqlick.com.
book.aiqlick.comA16.16.21.64Jitsi Meet (production EC2)
www.aiqlick.comCNAMEAmplify d36z3aolzpz5md.cloudfront.netFrontend prod
dev.aiqlick.comCNAMEAmplify distributionFrontend dev
storage.aiqlick.comCNAMECloudFront E4Z4UJZ2HEV46File CDN prod
storage-dev.aiqlick.comCNAMECloudFront E1PLDND9V3L62YFile CDN dev
docs.aiqlick.comCNAMECloudFront E158FQTQZ7MU1BDocumentation prod
docs-dev.aiqlick.comCNAMECloudFront E1ZZP7EF6S8BADocumentation dev
bg-{dev,prod}.aiqlick.localA (private)Cloud Map → ECS task ENIsInternal-only — backend → BG via internal ALB
DNS lives at one.com

There is no AWS Route 53 zone for aiqlick.com. DNS changes must be done in the one.com control panel — they cannot be automated through the AWS CLI or Terraform. This includes the ACM validation CNAMEs (_HASH.api(.dev).aiqlick.com.*.acm-validations.aws.) which ACM re-checks at every renewal. Don't delete those after issuance or the next renewal silently breaks.

SSL/TLS

ServiceCert sourceCert regionDomains
aiqlick-public-albACMeu-north-1api.aiqlick.com (CN), api-dev.aiqlick.com (SAN) — 644abb95-5a71-4d53-8118-e42630ad8096
CloudFront (storage)ACMus-east-1storage.aiqlick.com, storage-dev.aiqlick.com
CloudFront (docs)ACMus-east-1docs.aiqlick.com, docs-dev.aiqlick.com
AmplifyACMus-east-1www.aiqlick.com, dev.aiqlick.com
Jitsi EC2Let's Encrypt (Nginx + certbot)n/abook.aiqlick.com
Legacy backend/AI EC2s (zombies)Let's Encrypt (Caddy)n/aReachable but unused — pending termination
ACM region requirement
  • CloudFront / Amplify require certificates in us-east-1, regardless of where the origin lives.
  • ALBs require certificates in the same region as the ALB.

Traffic flows

API request

Backend → background-tasks (internal)

The backend addresses bg-tasks via the Cloud Map name bg-{env}.aiqlick.local. This name is registered to the internal ALB (not to the task ENIs directly), so requests get host-header routed to the right target group. This is what AI_BACKEND_GRAPHQL_URL in the backend task definition resolves to.

WebSocket subscriptions

URLPurpose
wss://api.aiqlick.com/graphqlBackend GraphQL subscriptions (notifications, log streaming, support events). Also subscribeAi — the gateway's single-document proxy for every AI subscription (CV extraction, job parsing, agent chat, etc.). See AI Gateway.
wss://api.aiqlick.com/voice/ws/{conversationId}Voice chat (raw PCM proxy through the gateway to background-tasks).

wss://ai.aiqlick.com/... URLs no longer exist in the frontend code — the gateway swallowed all four AI WS endpoints. The ai.aiqlick.com DNS record itself still resolves (to a zombie EC2) but nothing the frontend ships actually opens a connection to it.

WebRTC media (Jitsi)

SourceProtocolDestinationPurpose
BrowserHTTPS:443book.aiqlick.comWeb UI + signaling
BrowserUDP:10000book.aiqlick.comJVB media (video/audio)
JigasiUDP:20000+book.aiqlick.comTranscription audio (RTP)

Cross-region calls

ECS bg-tasks in eu-north-1 makes cross-region calls to AWS services in eu-west-1 (Rekognition for face detection, Transcribe for STT, Polly for TTS). These travel over the AWS backbone via the NAT gateway — ~20-30ms additional latency, acceptable since face detection is one-shot and transcription latency is hidden by streaming.

Environment isolation

Per-env isolation lives at the IAM, security-group, and SQS-queue level — not at the ECS-cluster or VPC level (one cluster + one VPC hosts both envs).

BoundaryDevProd
ECS servicebackend-dev, bg-tasks-devbackend-prod, bg-tasks-prod
Public ALB hostnameapi-dev.aiqlick.comapi.aiqlick.com
Cloud Map servicebg-dev.aiqlick.localbg-prod.aiqlick.local
RDSaiqlick-postgres-devaiqlick-postgres
S3 uploads bucketaiqlick-dev-uploadsaiqlick-uploads
Frontend (Amplify branch)dev (dev.aiqlick.com)main (www.aiqlick.com)
Secretsaiqlick-backend/developmentaiqlick-backend/production
Task rolesaiqlick-ecs-{backend,bg}-task-role-devaiqlick-ecs-{backend,bg}-task-role-prod
SQS queuesaiqlick-*-devaiqlick-*-prod

Troubleshooting

*.aiqlick.com returns a 500 from a non-AWS IP

If a hostname like https://api.aiqlick.com returns a generic Apache/Varnish 500 ("contact the server administrator at support@one.com") and resolves to 46.30.213.40 (or anything in the 46.30.213.0/24 block — see whois), the DNS record is parked at one.com rather than pointing at the intended AWS resource.

This typically happens when a record is deleted in the one.com control panel — one.com falls back to serving its own infrastructure for the bare hostname.

curl -sS -o /dev/null -w "Status: %{http_code}  IP: %{remote_ip}\n" https://api.aiqlick.com/health
dig +short @ns01.one.com api.aiqlick.com

If the IP is owned by One.com A/S (Denmark, AS31034), re-create the record in the one.com control panel. The expected target for the public ALB hostnames is:

api.aiqlick.com      ALIAS/CNAME  aiqlick-public-alb-2032682590.eu-north-1.elb.amazonaws.com.
api-dev.aiqlick.com ALIAS/CNAME aiqlick-public-alb-2032682590.eu-north-1.elb.amazonaws.com.

Before flipping DNS back, confirm the ALB has a :443 listener with a valid ACM cert covering the hostname (see "SSL/TLS" above).

ai-dev.aiqlick.com / ai.aiqlick.com health check fails

Expected — those records were deleted from one.com on 2026-05-14 as part of the Phase 7 cleanup. Both hostnames now fall through to one.com's parking IP 46.30.213.40 which serves an Apache 500 (see "*.aiqlick.com returns a 500 from a non-AWS IP" above). The FE doesn't call them — it goes through api(.dev).aiqlick.com via the AI gateway. If you want to reach dev background-tasks, exec into the bg-tasks-dev ECS task or call the internal Cloud Map name from inside the VPC — see SSM Operations.