Administrator
Published on 2026-02-14 / 0 Visits
0
0

DevOps Practice Note | Full Production Migration: EC2 → ECS + ALB

0. Migration Overview

This migration was not a simple frontend switch.

It was a full production architecture upgrade, including:

Data Layer

  1. EC2 local file system → S3 (gp-fileserver)

  2. EC2 MySQL (gp_sales_prod) → ECS-hosted DB (crm-db)

Application Layer Refactoring

  1. PHP monolith backend (main site + console + FX updater)

    → consolidated into ECS: crm-backend

  2. Console frontend (PHP-rendered pages)

    → extracted CRUD-only interface → ECS: crm-web

  3. Next.js main site frontend

    → new independent service ECS: gp-web

Traffic Layer

  1. ALB + Target Groups

  2. ACM certificate issuance

  3. Cloudflare DNS cutover

  4. Gradual EC2 decommission

This was a layered migration across:

Storage
Database
Backend
Frontend
Network
TLS
DNS

1. Storage Migration: EC2 → S3

Objective

Decouple file storage from compute instance.

Steps

  1. Identified static and uploaded files in EC2

  2. Synced to S3 bucket:

S3: gp-fileserver

  1. Updated backend file reference logic:

    • Replace local disk path

    • Store S3 object key

  2. Tested file upload & retrieval

Key Design Principle

  • Storage must be stateless

  • Application containers should not depend on local disk


2. Database Migration: EC2 → ECS DB (crm-db)

Objective

Separate DB from legacy EC2 and prepare for containerized architecture.

Steps

  1. Dump production DB:

mysqldump gp_sales_prod > dump.sql

  1. Import into ECS-hosted MySQL container:

mysql -h <crm-db-host> < dump.sql

  1. Resolve collation conflicts:

    • utf8mb4_0900_ai_ci vs utf8mb4_general_ci

  2. Update application DB connection configs

Lesson

DB migration issues are rarely infrastructure problems;

they are almost always:

  • Collation mismatch

  • Foreign key constraints

  • Charset differences


3. Backend Refactor: PHP Monolith → crm-backend

Legacy structure:

gp_sales_prod (PHP)
- Main site backend
- Admin backend
- FX updater

Refactored into:

ECS: crm-backend

Refactoring Goals

  • Separate business logic from view layer

  • Remove filesystem dependency

  • Centralize DB access

  • Prepare for future Java migration


4. Admin Frontend Simplification → crm-web

Legacy admin frontend was mixed with backend.

Refactored into:

ECS: crm-web

Scope reduced to:

  • News CRUD

  • FX CRUD

  • Minimal admin UI

Key principle:

Reduce surface area before migration.


5. New Service: Next.js → ECS: gp-web

This was the most complex part.

New Service Required:

  • New ECS Task Definition

  • New ECS Service

  • New Target Group (IP mode)

  • ALB Listener configuration

  • ACM certificate

  • Cloudflare DNS update


6. Network Architecture (Final State)

User
  ↓
Cloudflare DNS
  ↓
ALB (Internet-facing)
  ↓
Target Group (IP mode, HTTP:3000)
  ↓
ECS gp-web


7. Infrastructure Components Created

7.1 ALB

  • Scheme: Internet-facing

  • Listener:

    • HTTPS:443

  • ACM certificate bound

7.2 Target Group

  • Target type: IP (Fargate requirement)

  • Port: 3000

  • Health check: /

  • Success codes: 200-399

7.3 ECS

Task Definition:

  • Container port: 3000

  • Host binding: 0.0.0.0

Service:

  • Desired count: 1

  • Deployment strategy:

    • Minimum healthy percent = 100

    • Maximum percent = 200


8. Major Debugging Phases

This migration included layered debugging.


Phase 1: Timeout

Cause:

  • ALB Security Group missing 443

Fix:

HTTPS 443 → 0.0.0.0/0


Phase 2: Certificate Mismatch

Cause:

  • ACM missing www SAN

  • Wrong cert bound to listener

Fix:

  • DNS validation via Cloudflare

  • Rebind correct ACM cert


Phase 3: 504 Gateway Timeout

Cause:

  • ALB could not reach ECS port 3000

Fix:

  • ECS SG inbound TCP 3000 from ALB-SG


Phase 4: 503 Service Unavailable

Cause:

  • Target draining during deployment

  • No healthy target

Resolution:

  • Wait for registration

  • Adjust deployment config to prevent downtime


9. Final Cutover Strategy

Grey Release Plan

  1. Keep EC2 serving production

  2. Deploy ECS services

  3. Test via ALB DNS

  4. Validate:

    • File access

    • DB consistency

    • Admin CRUD

  5. Switch Cloudflare DNS to ALB

  6. Monitor

  7. Decommission EC2


10. Architectural Evolution

Before:

Single EC2
Filesystem + DB + PHP + Frontend

After:

S3 (storage)
ECS crm-db (database)
ECS crm-backend (API)
ECS crm-web (admin)
ECS gp-web (frontend)
ALB
Cloudflare DNS
ACM TLS


11. DevOps Maturity Achieved

This migration demonstrates capability in:

  • Layered infrastructure design

  • Zero-downtime deployment logic

  • Security Group modeling

  • Health check debugging

  • TLS and DNS validation

  • Stateful → stateless transformation


12. Most Valuable Insight

Error type maps directly to architectural layer:

Error

Layer

Timeout

Network / SG

Cert mismatch

TLS / ACM

504

ALB → Target connectivity

503

Target health

Understanding this mapping reduced debugging time dramatically.



Comment