# Bilko GCP→Azure Brand Domain Cutover (2026-06-15) — MC #103633

# Bilko GCP→Azure Brand Domain Cutover (2026-06-15) — MC #103633

## Context

 **Trigger:** GCP billing dead → all-to-Azure migration (CEO directive 2026-06-15).  
 **Scope:** Bilko web was already on Azure; `api.bilko.cloud` was DOWN (HTTP 000, no DNS record). Azure PostgreSQL `bilko-demo-pg` already populated (63 tables, seed data) so **NO DB migration needed** — flip-only cutover.

## What Changed

### 1. Cloudflare Worker Redeployment

- **Worker:** `bilko-edge-proxy`
- **New version:** `20b75f53-7e37-43c1-9145-4dc2364e8306`
- **Rollback target:** `707ad1ee-038c-459a-b7aa-588772d1bd49`
- **Routing:**
    - `api.bilko.{cloud,io,company}` → `bilko-api-demo.purplebeach-f004d490.swedencentral.azurecontainerapps.io`
    - `app.bilko.{cloud,io,company}` → `bilko-web-demo.purplebeach-f004d490.swedencentral.azurecontainerapps.io`

### 2. DNS Record Added

- **Zone:** `bilko.cloud` (Cloudflare)
- **Record:** `CNAME api.bilko.cloud` → `bilko-api-demo.purplebeach-f004d490.swedencentral.azurecontainerapps.io` (proxied)
- **Root cause fix:** `api.bilko.cloud` previously had NO DNS record → HTTP 000 failure

### 3. Configuration Verification

- `UNLEASH_URL` on `bilko-api-demo` already correct (Azure `bilko-unleash`), no change required

## Verification (PASS)

### Health Check — All 6 Brand Domains

<table border="1" cellpadding="6" id="bkmrk-endpoint-status-resp"> <thead> <tr> <th>Endpoint</th> <th>Status</th> <th>Response</th> </tr> </thead> <tbody> <tr> <td>`api.bilko.cloud/api/v1/health`</td> <td>✅ HTTP 200</td> <td>`{"status":"ok","service":"bilko-api"}`</td> </tr> <tr> <td>`api.bilko.io/api/v1/health`</td> <td>✅ HTTP 200</td> <td>`{"status":"ok","service":"bilko-api"}`</td> </tr> <tr> <td>`api.bilko.company/api/v1/health`</td> <td>✅ HTTP 200</td> <td>`{"status":"ok","service":"bilko-api"}`</td> </tr> <tr> <td>`app.bilko.cloud`</td> <td>✅ HTTP 200</td> <td>Next.js HTML (`lang="hr"`/`"sr-Latn"`/`"bs"`)</td> </tr> <tr> <td>`app.bilko.io`</td> <td>✅ HTTP 200</td> <td>Next.js HTML (`lang="hr"`/`"sr-Latn"`/`"bs"`)</td> </tr> <tr> <td>`app.bilko.company`</td> <td>✅ HTTP 200</td> <td>Next.js HTML (`lang="hr"`/`"sr-Latn"`/`"bs"`)</td> </tr> </tbody></table>

### Origin Confirmation

- **Azure origin confirmed:** All responses trace to Azure Container Apps (no GCP markers)
- **Auth path live:** `HTTP 410 ENDPOINT_RETIRED` → Entra SSO redirect working

### Independent Verification

- **Proveo E2E verdict:** PASS
- **Evidence:**
    - `/tmp/evidence-103633-flip/`
    - `/tmp/evidence-103633-dns2/`
    - `/tmp/evidence-103633-proveo-e2e/verification.md`

## Rollback Procedure

If issues arise, rollback the Cloudflare Worker:

```
wrangler rollback --name bilko-edge-proxy --version-id 707ad1ee-038c-459a-b7aa-588772d1bd49
```

## Open Follow-Ups (Low Priority)

1. **CSP cleanup:** `connect-src` on `app.bilko.cloud` still allowlists old GCP stage URL `bilko-api-stage-dh4m46blja-lz.a.run.app` — cosmetic, remove in cleanup PR.
2. **Worker repo commit:** Commit `/tmp/bilko-cf-worker/` to repo `apps/edge-proxy/` (MC #100129).
3. **Password rotation:** Rotate `bilko_admin` PG password (surfaced in session transcript).
4. **Service Principal:** Durable SP role grant on `rg-bilko-demo` (blocked by harness, needs CEO terminal).
5. **CI migration:** Replace dead GCP Cloud Build stage CI with Azure pipeline.

## Related Documentation

- **DEPLOY-MAP.md:** Updated with final Cloudflare Worker route table and DNS state (FlowForge-owned).
- **Parent MC:** #103633

---

*Published: 2026-06-15 | Author: Skillforge (ALAI Holding AS) | MC: #103633*