내부 문서

AWS 기반 확장형 웹서비스 기술 스택 안내

기술 스택 16분 읽기awscloud-architecturedocspublic-docweb-service

AWS 기반 확장형 웹서비스 기술 스택 안내

문서 개요

AWS 기반 확장형 웹서비스는 웹, API, 데이터베이스, 캐시, 비동기 Worker를 각각 분리하고 필요한 영역만 독립적으로 확장하는 구조입니다.

Vercel과 Supabase를 이용한 관리형 서버리스 구성이 빠른 출시와 낮은 초기 운영 부담에 적합하다면, AWS 구성은 네트워크 격리, 장시간 작업, 세밀한 확장 정책, 기존 기업 시스템 연동과 운영 통제가 중요할 때 적합합니다.

사용자가 많다는 이유만으로 AWS가 반드시 필요한 것은 아닙니다. 제품의 트래픽 특성, 처리 작업의 길이, 가용성 목표, 보안과 네트워크 요구사항, 운영 조직을 함께 검토해 선택합니다.

권장 전체 구조

사용자
  ↓
Route 53
  ↓
CloudFront + AWS WAF
  ↓
Application Load Balancer
  ↓
VPC
├─ ECS Fargate: Next.js 웹·API
├─ ECS Fargate: Worker ← SQS
├─ RDS PostgreSQL
└─ ElastiCache Redis

S3              파일 저장
SES             이메일 발송
Secrets Manager 인증정보 관리
CloudWatch      로그·지표·경보
ECR             컨테이너 이미지 저장

처음부터 여러 마이크로서비스로 나누기보다, 웹과 API는 하나의 명확한 애플리케이션 경계로 시작하고 비동기 Worker만 별도 실행 단위로 분리하는 구성이 이해와 운영에 유리합니다.

기본 기술 스택

영역 권장 구성 역할
도메인·DNS Route 53 도메인 레코드와 트래픽 연결
CDN CloudFront 정적 자산 캐시와 전 세계 전송
웹 방화벽 AWS WAF 알려진 공격 패턴과 비정상 요청 제어
로드 밸런서 Application Load Balancer HTTPS 요청을 ECS 작업에 분배
웹·API Next.js standalone, ECS Fargate 화면 렌더링과 API 실행
컨테이너 저장소 Amazon ECR 배포할 컨테이너 이미지 보관
관계형 DB Amazon RDS for PostgreSQL 업무 데이터와 트랜잭션 저장
캐시 Amazon ElastiCache for Redis 캐시, 세션, 빠른 임시 상태 저장
작업 큐 Amazon SQS API와 비동기 Worker 분리
Worker ECS Fargate 서비스 알림, 파일 처리, 집계 등 후처리 수행
파일 Amazon S3 업로드 파일과 정적 자산 저장
인증 Amazon Cognito 또는 별도 인증 계층 사용자 로그인과 토큰 발급
이메일 Amazon SES 인증·알림·업무 이메일 발송
인증정보 AWS Secrets Manager DB 비밀번호와 외부 서비스 인증정보 보관
로그·모니터링 Amazon CloudWatch 로그, 지표, 대시보드, 경보
인프라 코드 AWS CDK, Terraform 또는 CloudFormation 인프라 변경 이력과 재현 가능한 배포
CI/CD GitHub Actions, ECR, ECS 테스트, 이미지 빌드, 서비스 배포

ElastiCache, Cognito, SES 같은 서비스는 요구사항이 있을 때 선택합니다. 모든 항목을 첫 배포부터 구성해야 하는 것은 아닙니다.

웹·API 실행 구조

Next.js 애플리케이션은 standalone 모드로 컨테이너 이미지를 만들고 ECS Fargate에서 실행할 수 있습니다. Application Load Balancer는 HTTP와 HTTPS 요청을 여러 ECS 작업에 분배하고 상태가 정상인 작업으로만 트래픽을 전달합니다.

CloudFront
    ↓
Application Load Balancer
    ├─ Next.js Task A
    ├─ Next.js Task B
    └─ Next.js Task C

트래픽이 늘어나면 CPU, 메모리, 요청량 같은 CloudWatch 지표를 기준으로 ECS 작업 수를 늘리고, 감소하면 다시 줄일 수 있습니다. 확장 기준은 단순히 CPU 하나만 보지 않고 애플리케이션의 실제 병목과 연결되는 지표를 선택합니다.

정적 파일은 S3와 CloudFront에서 제공하고, 서버 렌더링과 API 요청만 ECS로 보내면 애플리케이션 작업의 부하를 줄일 수 있습니다.

VPC와 네트워크 분리

VPC는 AWS 자원을 배치하는 논리적 사설 네트워크입니다. 외부에서 직접 접근할 필요가 없는 ECS 작업, RDS, Redis는 Private Subnet에 배치하고 공개 진입점만 제한적으로 노출합니다.

Public 진입 영역
└─ CloudFront · WAF · Load Balancer

Private Subnet
├─ ECS 웹·API
├─ ECS Worker
├─ RDS PostgreSQL
└─ ElastiCache Redis

CloudFront 뒤에 Application Load Balancer를 둘 때는 CloudFront를 거치지 않은 직접 접근을 제한하거나, 요구사항에 따라 CloudFront VPC Origin과 내부 Load Balancer 구성을 검토할 수 있습니다.

Private Subnet의 애플리케이션이 외부 API에 요청하려면 NAT Gateway 같은 외부 통신 경로가 필요할 수 있습니다. S3 등 지원되는 AWS 서비스는 VPC Endpoint를 이용하면 NAT를 거치지 않는 사설 연결을 구성할 수 있습니다.

데이터베이스 구성

기본 데이터베이스는 RDS for PostgreSQL을 사용합니다.

  • 자동 백업과 복구 정책을 설정합니다.
  • 운영 환경은 가용성 목표에 따라 Multi-AZ를 검토합니다.
  • 애플리케이션과 DB의 연결 수를 제한하고 모니터링합니다.
  • 읽기 부하가 커지면 Read Replica 또는 다른 읽기 확장 방식을 검토합니다.
  • 스키마 변경은 애플리케이션 배포와 분리된 절차로 관리합니다.

RDS Multi-AZ는 다른 가용 영역에 동기식 대기 복제본을 유지하고 장애 시 전환하는 고가용성 구성입니다. 일반적인 단일 대기 복제본 방식에서 대기 복제본은 읽기 트래픽을 처리하는 용도가 아니므로, 고가용성과 읽기 확장을 구분해야 합니다.

연결이 급격히 늘어나는 구조에서는 RDS Proxy 같은 연결 관리 계층을 추가로 검토할 수 있지만, 애플리케이션의 연결 패턴을 먼저 확인한 뒤 도입합니다.

비동기 Worker 구조

사용자 요청 안에서 끝낼 필요가 없는 작업은 SQS에 메시지를 넣고 Worker가 처리하게 합니다.

사용자 → 웹·API → 즉시 응답
                  ↓
                 SQS
                  ↓
       ECS Worker × 필요한 수
                  ↓
        DB 갱신 · 파일 처리 · 알림

적합한 작업의 예시는 다음과 같습니다.

  • 이메일과 알림 발송
  • 이미지, 문서, 동영상 후처리
  • 외부 API 동기화
  • 통계 집계와 보고서 생성
  • 대량 데이터 가져오기와 내보내기

SQS는 웹·API와 Worker를 느슨하게 분리합니다. Worker 수는 큐에 쌓인 메시지 수와 처리 지연 시간을 기준으로 확장할 수 있습니다.

메시지는 재전달될 수 있으므로 Worker는 같은 작업을 여러 번 받아도 결과가 중복되지 않도록 멱등하게 구현합니다. 반복 실패한 메시지는 Dead Letter Queue로 이동시키고 운영자가 원인을 확인할 수 있게 합니다.

Redis가 필요한 시점

ElastiCache Redis는 다음과 같이 매우 빠른 임시 상태가 필요할 때 사용합니다.

  • 자주 조회하지만 자주 바뀌지 않는 데이터 캐시
  • 로그인 세션과 짧은 수명의 상태
  • 요청 제한과 중복 요청 방지
  • 짧은 잠금과 실시간 상태 공유

PostgreSQL만으로 충분한 초기 단계에서는 Redis를 생략할 수 있습니다. Redis를 도입하면 캐시 만료, 데이터 불일치, 장애 시 동작을 함께 설계해야 하므로 조회 부하나 응답 시간 문제가 확인된 뒤 추가하는 편이 안전합니다.

파일과 정적 자산

사용자가 업로드한 파일은 애플리케이션 컨테이너의 로컬 디스크가 아니라 S3에 저장합니다. ECS 작업은 교체되거나 여러 개로 늘어날 수 있으므로 로컬 파일을 영구 저장소로 사용하지 않습니다.

  • 파일은 기본적으로 비공개로 저장합니다.
  • 업로드와 다운로드에는 제한된 시간의 서명 URL을 사용할 수 있습니다.
  • 파일 크기, 형식, 개수와 보관 기간을 제한합니다.
  • 정적 자산은 CloudFront를 통해 캐시합니다.
  • 중요한 파일은 버전 관리, 수명 주기, 백업 요구사항을 검토합니다.

배포 구조

GitHub Push
    ↓
GitHub Actions
    ├─ 테스트
    ├─ 컨테이너 이미지 빌드
    └─ ECR 업로드
          ↓
      ECS 서비스 배포
          ↓
   상태 확인 후 트래픽 전환

GitHub Actions는 장기 AWS 접근 키를 저장하는 대신 OIDC와 짧은 수명의 역할 자격증명을 이용하는 구성을 권장합니다. 배포 시 새 작업이 정상 상태가 된 뒤 이전 작업을 종료하도록 하고, 실패하면 기존 버전이 계속 동작할 수 있게 합니다.

데이터베이스 스키마 변경은 컨테이너 시작과 무조건 묶지 않습니다. 여러 작업이 동시에 마이그레이션을 실행하지 않도록 별도의 단일 배포 단계로 관리합니다.

운영 가용성

중요한 운영 서비스는 하나의 인스턴스나 하나의 가용 영역에만 의존하지 않도록 구성합니다.

  • ECS 웹·API 작업을 두 개 이상의 가용 영역에 분산
  • Application Load Balancer 상태 확인 적용
  • RDS Multi-AZ와 자동 백업 검토
  • Worker 자동 확장과 Dead Letter Queue 적용
  • CloudWatch 지표·로그·경보 구성
  • 외부 의존 서비스의 시간 제한과 재시도 정책 정의
  • 정기적인 복구 절차 점검

가용성 구성은 비용과 함께 증가합니다. 모든 개발·검증 환경을 운영 환경과 같은 크기로 유지하기보다 환경별 목표를 정하고 필요한 수준으로 구성합니다.

보안 원칙

  • RDS와 Redis는 외부 인터넷에 공개하지 않습니다.
  • Security Group은 실제 통신 주체와 포트만 허용합니다.
  • ECS 작업에는 필요한 권한만 가진 IAM Role을 부여합니다.
  • 비밀값은 이미지, 소스 코드, CI 로그에 넣지 않습니다.
  • S3 버킷은 기본 비공개로 두고 공개 범위를 명시적으로 관리합니다.
  • CloudFront와 Load Balancer 사이에도 HTTPS를 적용합니다.
  • 관리자 기능과 일반 사용자 기능의 인증·권한을 분리합니다.
  • WAF는 애플리케이션 검증을 대신하지 않으며 보조 방어 계층으로 사용합니다.
  • 로그의 개인정보와 보관 기간을 관리합니다.

비용 구조를 이해하는 방법

AWS는 서비스별 비용이 분리되므로 사용량이 적어도 발생하는 비용과 사용량에 따라 증가하는 비용을 구분해야 합니다.

기본적으로 지속되는 비용

  • 실행 중인 ECS Fargate 작업
  • Application Load Balancer
  • RDS 인스턴스와 저장소
  • NAT Gateway를 구성한 경우의 시간 비용
  • 운영 수준에 따른 Multi-AZ 자원

사용량에 따라 달라지는 비용

  • CloudFront 전송량과 요청
  • S3 저장량과 요청
  • SQS 메시지 요청
  • SES 이메일 발송량
  • CloudWatch 로그 저장과 조회
  • NAT Gateway 데이터 처리량
  • 가용 영역과 인터넷 사이의 데이터 전송

특히 NAT Gateway는 실행 시간과 처리한 데이터 양을 함께 확인해야 합니다. 로그 보관 기간, 불필요한 개발 환경, 과도한 최소 작업 수, 사용하지 않는 Load Balancer와 스냅샷도 정기적으로 점검합니다.

관리형 서버리스 구성과 비교

관리형 서버리스 구성 AWS 확장형 구성
Vercel Hosting CloudFront + Load Balancer + ECS Fargate
Vercel Functions ECS Fargate 또는 Lambda
Supabase PostgreSQL RDS PostgreSQL 또는 Aurora PostgreSQL
Supabase Auth Amazon Cognito
Supabase Storage Amazon S3
Upstash Redis Amazon ElastiCache for Redis
Upstash QStash Amazon SQS + EventBridge
Resend Amazon SES
Vercel Logs Amazon CloudWatch

이 표는 기능의 대략적인 대응 관계이며 완전히 동일한 제품을 의미하지 않습니다. 관리형 서버리스는 적은 운영 인력으로 빠르게 출시하기 좋고, AWS 확장형 구성은 네트워크와 실행 환경을 더 세밀하게 통제할 수 있는 대신 설계와 운영 책임이 커집니다.

AWS 구성이 잘 맞는 경우

  • VPC 안에서 애플리케이션과 데이터를 격리해야 하는 경우
  • 웹·API와 여러 Worker를 독립적으로 확장해야 하는 경우
  • 수십 분 이상 실행되는 비동기 작업이나 상시 처리 프로세스가 있는 경우
  • 기업 사설망, 전용 연결, 기존 AWS 시스템과 연동해야 하는 경우
  • 가용 영역, 네트워크 경로, 배포 방식을 세밀하게 통제해야 하는 경우
  • 인프라를 코드로 관리할 운영 조직이 있는 경우

반대로 서비스 요구사항이 단순하고 빠른 출시가 우선이며 별도의 클라우드 운영 인력이 없다면 Vercel과 Supabase 같은 관리형 구성이 더 합리적일 수 있습니다.

더 큰 플랫폼 단계에서의 EKS

많은 팀이 다수의 컨테이너 서비스를 운영하고 Kubernetes 생태계, 공통 배포 표준, 세밀한 스케줄링이 필요한 단계에서는 Amazon EKS를 검토할 수 있습니다. 다만 클러스터, 네트워크, 업그레이드, 관측 체계를 운영해야 하므로 단순히 트래픽이 많다는 이유만으로 선택하지 않습니다. 이 문서의 기본 권장 구성에는 EKS를 포함하지 않으며, ECS Fargate로 해결하기 어려운 구체적인 요구가 확인될 때 다음 단계로 평가합니다.

참고 문서

구체적인 서비스와 가용성 구성은 예상 트래픽, 장애 허용 범위, 데이터 특성, 외부 연동, 운영 인력과 예산을 검토한 뒤 결정합니다.