Skip to content

Production — after the ALB migration

This describes the intended end state once the in-flight Terraform work (6 PRs against infra-base, JIRA EC-4046) is merged, applied, and cut over. Compare against today's state. Marked clearly where the plan isn't fully solid yet.

Traffic flow (target state)

%%{init: {'flowchart': {'nodeSpacing': 70, 'rankSpacing': 110, 'padding': 20, 'curve': 'basis'}}}%%
flowchart TB
    Internet((Public Internet))

    subgraph DNS["Route 53 — prod account"]
        direction TB
        AC["arep.co"]
        ACC["arep.cc"]
        AI["arep.ink"]
        AT["automated.arep.co"]
        APP["app.audiencerepublic.com<br/>(unchanged)"]
        PORTAL["&lt;promoter&gt;.portal.arep.co<br/>NOT in migration scope"]
    end

    subgraph ALB["alb-apse2-prod-server"]
        direction TB
        WAF["WAF Web ACL<br/>IP denylist + Googlebot rule"]
        LISTENER["HTTPS listener, SNI certs<br/>for arep.co / arep.cc / arep.ink"]
        RULES["Host + path listener rules"]
        WAF --> LISTENER --> RULES
    end

    subgraph TG["Target groups"]
        direction TB
        TGCN["tg_prod_cn, tg_prod_external_api,<br/>tg_prod_ingest, tg_prod_share_analytics,<br/>tg_prod_static"]
        TGAM["tg_prod_am"]
        TGSG["tg_prod_sg"]
        TGAT["tg_prod_automated_testing (+3 port variants)"]
        TGMON["tg_prod_monitor"]
    end

    subgraph BACKEND["Same backend fleet as today, reached over existing VPC peering"]
        direction TB
        CN["campaign-1 / 2 / 3"]
        AM["audience-manager-1 / 2"]
        COL["collector-1"]
        ATEST["automated-testing"]
        MON["monitor backend — confirmed dead,<br/>connection refused on port 5000"]
    end

    subgraph GW["nginx gateways"]
        direction TB
        GW1["gateway1 — role after cutover unresolved,<br/>see risks below"]
        GWSHORT["gateway-short-url — fully retired"]
    end

    Internet --> AC & ACC & AI & AT & APP & PORTAL
    AC --> RULES
    ACC --> RULES
    AI --> RULES
    AT --> RULES
    RULES --> TGCN & TGAM & TGSG & TGAT & TGMON
    TGCN --> CN
    TGAM --> AM
    TGSG --> COL
    TGAT --> ATEST
    TGMON --> MON
    PORTAL -.->|not migrated, depends on gateway1 surviving| GW1

What changes

Hostname Today After migration
arep.co Route 53 Failover → nginx gateway1/gateway2 ALB host/path listener rules → target groups
arep.cc Route 53 Weighted → nginx gateway2 (broken fallback leg) ALB, SNI cert, listener rule → tg_prod_cn
arep.ink Simple A → nginx gateway2 ALB, SNI cert, listener rule → tg_prod_cn
automated.arep.co Dead, resolves to an unassociated EIP ALB → 4 target groups (one per port the automated-testing host serves)
WAF None IP denylist (4 known addresses) + a Googlebot block scoped only to automated.arep.co/staging
Alarms None Per-target-group unhealthy/no-healthy alarms, plus ALB-level 5xx/latency alarms
gateway-short-url Zombie, no DNS points at it Terminated
gateway1 / gateway2 Serve all reverse-proxy traffic Reverse-proxy role removed; whether they're downsized or fully retired is unresolved, see below

Known risks to this target state

  • tg_prod_monitor's backend is confirmed dead, not just unconfirmed. A live connectivity test from inside the VPC gets Connection refused on port 5000 for both campaign-1 and campaign-2 — the hosts are reachable, nothing is listening. The target group is still provisioned as planned; its unhealthy/no-healthy alarms will fire and stay in ALARM state immediately once applied.
  • Privacy Portal is confirmed real and active, settling the earlier ambiguity over whether an old decommission checklist's "unused" assumption was correct — test.portal.arep.co returns a live 405 with a JSON body and CORS headers today. It's still not part of this migration's scope, and depends entirely on gateway1 continuing to exist in some form; if gateway1 is fully retired rather than downsized, this breaks. Separately, and unrelated to the migration: its TLS certificate expired 2026-07-29, so real clients already get a hard TLS error today, independent of anything in this plan.
  • Whether gateway1/gateway2 get downsized or fully retired is an open question. The original plan assumed they still need to keep running because they serve app.audiencerepublic.com's static files. A separate audit found that hostname is already served by Netlify, not the gateways, which may make full retirement possible, pending confirmation, and pending the Privacy Portal question above — and pending /zoomverify/, confirmed still served directly from gateway disk today (unmigrated to S3+CloudFront), which also has nowhere to live if the gateways go away.